cvs commit: src/sys/net if_ethersubr.c

Bruce Evans bde at
Tue Dec 12 07:18:12 PST 2006

On Tue, 12 Dec 2006, Luigi Rizzo wrote:

> On Tue, Dec 12, 2006 at 02:13:34PM +0100, Bernd Walter wrote:
>> On Fri, Dec 08, 2006 at 10:36:46AM +0000, Luigi Rizzo wrote:
>>> luigi       2006-12-08 10:36:45 UTC
>>>   FreeBSD src repository
>>>   Modified files:
>>>     sys/net              if_ethersubr.c
>>>   Log:
>>>   Fix an oscure bug triggered by a recent change in kern_socket.c.
>> This change produces an alignment panic on arm.
>> Reverting it gets my system back to live.

Something reduced my ttcp tx bandwidth for tiny packets on an i386 (Athlon
XP 2700 overclocked) from 350 kpps to 300 kpps (after I thought increased
it from 320-330 kpps to 350-360 kpps) by reducing copying).  I suspected
this commit, then misalignment.  I still suspect alignment...

> then i suppose the proper fix is to revert to m_copy() and
> work on if_simloop() so that 1. it handles a readonly chain, and
> 2. when doing so, it passes up a properly aligned packet...
> however note that there is already some code in net/if_loop.c::if_simloop(),
> just that it uses this:
> 	#if defined(__ia64__) || defined(__sparc64__)
>                /*
>                 * Some archs do not like unaligned data, so
>                 * we move data down in the first mbuf.
>                 */
>                if (mtod(m, vm_offset_t) & 3) {
>                        KASSERT(hlen >= 3, ("if_simloop: hlen too small"));
>                        bcopy(m->m_data,
>                            (char *)(mtod(m, vm_offset_t)
>                                - (mtod(m, vm_offset_t) & 3)),
>                            m->m_len);
>                        m->m_data -= (mtod(m,vm_offset_t) & 3);
>                }
> 	#endif
> to detect whether the architecture is alignment-sensitive.
> Is there any other identifier that we can use to check ?

__NO_STRICT_ALIGNMENT.  Many drivers already use this.  It's stiall an
abuse since __FOO is in the implementation namespace, and of course
__NO_STRICT_ALIGNMENT is documented mainly (only?) in its log message.

No arches "like" unaligned data; some just handle it without trapping
or other extreme slowness.  I think copying of data to fix its alignment
is best for most arches if the data is small but not if it is large.

About my ttcp tx bandwith problem:
- tx is almost entirely syscall-bound (< 2-4% interrupt overhead)
- the slowdown was mostly caused by adding about 500 bytes in unrelated
   code (in nfs_diskless.c) that was never executed.  Removing these bytes
   or moving nfs_diskless.o to the end of the object file list recovered
   30-40 kpps of the lost bandwidth.  It looks like there are lots of
   cache conflicts for the I-cache, but I thought that this problem mostly
   went away with i486's.
- the bandwidth depended mysteriously on related and unrelated previous
   changes, but no single change (including ones that added much more than
   500 bytes) affected it by as much as 360 -> 300.
- the bandwidth also depends on the ttcp binary and has a high variance
   in separate runs (but not in the same run).  I now suspect that I-cache
   conflicts cause this too.
- I found some silly data alignment that doesn't seem to affect ttcp.
   struct sockaddr is essentially char [16] so it asks for pessimal
   alignment (not misalignment unless it is type punned).  I think gcc
   normally gives struct sockaddr's on the stack 4-byte alignment.
   sun_noname is perfectly misaligned in all my kernels, because it
   happens to get allocated after some strings with an odd total size
   in the read-only text section.  It is a sockaddr, not a sockaddr_un
   despite its name.  struct sockaddr_un is essentially char [106],
   so it also asks for pessimal alignment, with more cost since it is
   quite large.  Grepping nm output showed this some other alignment
   problems.  E.g., futex functions in i386/support.s have random
   alignment and other bugs caused by not using ENTRY() for them.


More information about the cvs-all mailing list