Date: Wed, 7 Jul 2010 23:07:37 +0800 From: Adrian Chadd <adrian@freebsd.org> To: adrian@freebsd.org, freebsd-bugs@freebsd.org Subject: Re: kern/148307: Incorrect alignment checks in sys/mips/atheros/if_arge.c Message-ID: <AANLkTiktiWCI6ltVnuEWDmp98TkPouqKDToKb0A09K2C@mail.gmail.com> In-Reply-To: <201007020941.o629flk5044526@freefall.freebsd.org> References: <201007020941.o629flk5044526@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
This patch hasn't been tested. Oleksandr wanted to check the chain its
in entirety.
--- if_arge.c (revision 209765)
+++ if_arge.c (working copy)
@@ -818,6 +818,28 @@
}
/*
+ * Return whether the mbuf chain is correctly aligned
+ * for the arge TX engine.
+ *
+ * The TX engine requires each fragment to be aligned to a
+ * 4 byte boundary and the size of each fragment except
+ * the last to be a multiple of 4 bytes.
+ */
+static int
+arge_mbuf_chain_is_tx_aligned(struct mbuf *m0)
+{
+ struct mbuf *m;
+
+ for (m = m0; m != NULL; m = m->m_next) {
+ if((mtod(m, intptr_t) & 3) != 0)
+ return 0;
+ if ((m->m_next != NULL) && ((m->m_len & 0x03) != 0))
+ return 0;
+ }
+ return 1;
+}
+
+/*
* Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
* pointers to the fragment pointers.
*/
@@ -837,7 +859,7 @@
* even 4 bytes
*/
m = *m_head;
- if((mtod(m, intptr_t) & 3) != 0) {
+ if (! arge_mbuf_chain_is_tx_aligned(m)) {
m = m_defrag(*m_head, M_DONTWAIT);
if (m == NULL) {
*m_head = NULL;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTiktiWCI6ltVnuEWDmp98TkPouqKDToKb0A09K2C>
