Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Dec 2006 15:17:59 +0100
From:      Bernd Walter <ticso@cicely12.cicely.de>
To:        Luigi Rizzo <rizzo@icir.org>
Cc:        Luigi Rizzo <luigi@FreeBSD.org>, src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org, imp@FreeBSD.org, ticso@cicely.de
Subject:   Re: cvs commit: src/sys/net if_ethersubr.c
Message-ID:  <20061212141759.GZ54209@cicely12.cicely.de>
In-Reply-To: <20061212055756.A61182@xorpc.icir.org>
References:  <200612081036.kB8AakMD029277@repoman.freebsd.org> <20061212131333.GU54209@cicely12.cicely.de> <20061212055756.A61182@xorpc.icir.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Dec 12, 2006 at 05:57:56AM -0800, 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.
> > >   The symptoms were that outgoing DHCP requests for diskless kernels
> > >   had the IP header corrupt. After long investigations, the source of
> > >   the problem was found in ether_output() - for SIMPLEX interfaces
> > >   and broadcast traffic, a copy of the packet is passed back to the kernel
> > >   through if_simloop(). However if_simloop() modifies the mbuf, while
> > >   the copy obtained through m_copym() is a readonly one.
> > >   
> > >   The bug has been there forever, but it has been triggered only recently
> > >   by a change in sosend_dgram() which passed down mbufs with sufficient
> > >   space to prepend the header.
> > >   
> > >   This fix is trivial - use m_dup() instead of m_copy() to create
> > >   the copy. As an alternative, we could try and modify if_simloop()
> > >   to play safely with readonly mbufs, but i don't think it is worthwhile
> > >   because 1) this is a relatively infrequent code path so we do not need
> > >   to worry too much about performance, and 2) the cost of doing an
> > >   extra m_pullup in if_simloop() is probably the same as doing the
> > >   copy of the cluster, anyways.
> > 
> > This change produces an alignment panic on arm.
> > Reverting it gets my system back to live.
> 
> 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...

Can't comment on this, as I don't have enough knowledge about network
code.
According to the xscale report it was likely never properly aligned,
the alignment obviously just moved with your change.

> 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 ?

I wonder how many of these are missing __arm__?

-- 
B.Walter                http://www.bwct.de      http://www.fizon.de
bernd@bwct.de           info@bwct.de            support@fizon.de



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061212141759.GZ54209>