alpha and em mtu
Sten Spans
sten at blinkenlights.nl
Sat Nov 27 16:00:53 PST 2004
On Tue, 23 Nov 2004, John Baldwin wrote:
> On Monday 22 November 2004 10:09 pm, Sten Spans wrote:
>> 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.2
>>> 2&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.
>
> We do need some kind of __STRICT_ALIGNMENT macro I think if we don't already
> have one as archs other than i386 might not need the alignment.
bge needs some fixing as well then:
2773 #ifndef __i386__
2774 /*
2775 * The i386 allows unaligned accesses, but for other
2776 * platforms we must make sure the payload is aligned.
2777 */
2778 if (sc->bge_rx_alignment_bug) {
2779 bcopy(m->m_data, m->m_data + ETHER_ALIGN,
2780 cur_rx->bge_len);
2781 m->m_data += ETHER_ALIGN;
2782 }
2783 #endif
Not sure if this a better fix for the same problem...
> At the least
> there could be a block near the top of if_em.h that was:
>
> #if defined(__alpha__)
> #define STRICT_ALIGNMENT
> #endif
>
> and other architectures could be fixed by simply adding another
> 'defined(__foo__)' clause without having to change the ifdef and comments
> down in the code itself.
I've attatched an updated version of the patch, with your comment
included.
> As to the correctness of the em(4) change,
> hopefully Robert can speak to that.
Have you had time to look at this robert ?
--
Sten Spans
"There is a crack in everything, that's how the light gets in."
Leonard Cohen - Anthem
-------------- next part --------------
--- if_em.c.orig Tue Nov 23 03:03:23 2004
+++ if_em.c Sun Nov 28 00:53:51 2004
@@ -2784,8 +2784,57 @@
/* Assign correct length to the current fragment */
mp->m_len = len;
+#ifndef __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.
+ */
+ 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 /* __STRICT_ALIGNMENT */
+
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 Sun Nov 28 00:53:13 2004
@@ -79,6 +79,10 @@
#include <dev/em/if_em_hw.h>
+#if defined(__alpha__)
+#define __STRICT_ALIGNMENT
+#endif
+
/* Tunables */
/*
@@ -346,6 +350,12 @@
int io_rid;
u_int8_t unit;
struct mtx mtx;
+
+#ifndef __STRICT_ALIGNMENT
+ /* 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 /* __STRICT_ALIGNMENT */
/* Info about the board itself */
u_int32_t part_num;
More information about the freebsd-alpha
mailing list