Date: Tue, 23 Nov 2004 04:09:20 +0100 (CET) From: Sten Spans <sten@blinkenlights.nl> To: John Baldwin <jhb@FreeBSD.org> Cc: freebsd-alpha@FreeBSD.org Subject: Re: alpha and em mtu Message-ID: <Pine.SOC.4.61.0411230406010.10997@tea.blinkenlights.nl> In-Reply-To: <Pine.SOC.4.61.0411230259030.10997@tea.blinkenlights.nl> References: <Pine.SOC.4.61.0411142153430.26307@tea.blinkenlights.nl> <Pine.SOC.4.61.0411222147180.10997@tea.blinkenlights.nl> <Pine.SOC.4.61.0411230026430.10997@tea.blinkenlights.nl> <Pine.SOC.4.61.0411230259030.10997@tea.blinkenlights.nl>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 23 Nov 2004, Sten Spans wrote: >> doesn't seem to print anything, but ... >> >> if_em.c >> 2442 >> 2443 /*if (ifp->if_mtu <= ETHERMTU) { */ >> 2444 m_adj(mp, ETHER_ALIGN); >> 2445 /*} */ >> 2446 >> >> does seem to fix the crash, also trashes the performance, >> but that's another matter. It looks like mbuf alignment is >> needed, if_bge seems to provide reasonable examples. > > And looking at netbsd/openbsd clarifies the whole issue, > > #ifdef __STRICT_ALIGNMENT > /* > * The ethernet payload is not 32-bit aligned when > * Jumbo packets are enabled, so on architectures > with > * strict alignment we need to shift the entire > packet > * ETHER_ALIGN bytes. Ugh. > */ > > > This diff probably should be merged. > http://www.openbsd.org/cgi-bin/cvsweb/src/sys/dev/pci/if_em.c.diff?r1=1.22&r2=1.23 > > Although I don't know wether freebsd has the STRICT_ALIGNMENT define. This is an initial patch based on the openbsd code, which solves the if_em issue, and seems to give ok performance ( note to self: turn off debugging when testing network performance ). Comments welcome. --- if_em.c.orig Tue Nov 23 03:03:23 2004 +++ if_em.c Tue Nov 23 03:20:15 2004 @@ -2784,8 +2784,57 @@ /* Assign correct length to the current fragment */ mp->m_len = len; +#ifndef __i386__ + /* + * The ethernet payload is not 32-bit aligned when + * Jumbo packets are enabled, so on architectures with + * strict alignment we need to shift the entire packet + * ETHER_ALIGN bytes. Ugh. + */ + if (ifp->if_mtu > ETHERMTU) { + unsigned char tmp_align_buf[ETHER_ALIGN]; + int tmp_align_buf_len = 0; + + if (prev_len_adj > adapter->align_buf_len) + prev_len_adj -= adapter->align_buf_len; + else + prev_len_adj = 0; + + if (mp->m_len > MCLBYTES - ETHER_ALIGN) { + bcopy(mp->m_data + + (MCLBYTES - ETHER_ALIGN), + &tmp_align_buf, + ETHER_ALIGN); + tmp_align_buf_len = mp->m_len - + (MCLBYTES - ETHER_ALIGN); + mp->m_len -= ETHER_ALIGN; + } + + if (mp->m_len) { + bcopy(mp->m_data, + mp->m_data + ETHER_ALIGN, + mp->m_len); + if (!adapter->align_buf_len) + mp->m_data += ETHER_ALIGN; + } + + if (adapter->align_buf_len) { + mp->m_len += adapter->align_buf_len; + bcopy(&adapter->align_buf, + mp->m_data, + adapter->align_buf_len); + } + + if (tmp_align_buf_len) + bcopy(&tmp_align_buf, + &adapter->align_buf, + tmp_align_buf_len); + adapter->align_buf_len = tmp_align_buf_len; + } +#endif /* __386__ */ + if (adapter->fmp == NULL) { - mp->m_pkthdr.len = len; + mp->m_pkthdr.len = mp->m_len; adapter->fmp = mp; /* Store the first mbuf */ adapter->lmp = mp; } else { @@ -2801,7 +2850,7 @@ } adapter->lmp->m_next = mp; adapter->lmp = adapter->lmp->m_next; - adapter->fmp->m_pkthdr.len += len; + adapter->fmp->m_pkthdr.len += mp->m_len; } if (eop) { --- if_em.h.orig Wed Nov 10 03:18:52 2004 +++ if_em.h Tue Nov 23 03:33:01 2004 @@ -347,6 +347,12 @@ u_int8_t unit; struct mtx mtx; +#ifndef __i386__ + /* Used for carrying forward alignment adjustments */ + unsigned char align_buf[ETHER_ALIGN]; /* tail of unaligned packet */ + u_int8_t align_buf_len; /* bytes in tail */ +#endif /* __i386__ */ + /* Info about the board itself */ u_int32_t part_num; u_int8_t link_active; -- Sten Spans "There is a crack in everything, that's how the light gets in." Leonard Cohen - Anthem
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.SOC.4.61.0411230406010.10997>