Subject: Re: Small Ethernet packet padding
To: None <cube@cubidou.net>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-net
Date: 10/31/2004 13:33:11
On Sun, Oct 31, 2004 at 12:18:29PM +0100, cube@cubidou.net wrote:
> Hi,
> 
> Yesterday while working on some different issue, I could see
> that gem(4) did not pad small Ethernet packets.  That means
> you get data from the kernel on the wire at the trailing of
> those packets.
> 
> When that issue was covered last year (I think it was last
> year, at least), Manuel Bouyer made changes to the affected
> drivers at that time.
> 
> However, I was suggested yesterday by Matt Thomas to take a
> more general approach and handle that issue at the Ethernet
> layer of the kernel.
> 
> With the help of Emmanuel Dreyfuss I've come up with the
> attached patch.  It works fairly well, even though it had
> some limited testing, but I'm still wondering if there are
> any other (and possibly better) ways to manipulate the
> mbuf chain.
> 
> >From our tests, it appears that having space already inside
> the mbuf is clearly not a given.  At least freshly after
> the boot, there is about never enough space, except for
> a certain length, because the size is 32-bits aligned.  I
> guess we don't get space 'other than from alignment) when
> the mbuf storage is external.  I haven't actually checked
> that.
> 
> As my knowledge in the mbuf area is limited so there might
> be ways of making the m_clrhdr/m_cat step simpler.  I'm
> open to suggestions.
> 
> Also, I wonder what is the gain of making the padding at
> the driver level.  I'd like some input there too.  If
> there is no actual advantage to doing that inside the
> hardware driver, I think it would be best to convert all
> affected drivers to such a scheme as the low-level padding
> adds quite some complexity to the driver.

The problem with doing this at the the ethernet level is that
it will always cost you extra CPU cycles. 
- if the adapter is doing PIO, just write a buch of 0 to the I/O port,
  no need to extend the packet. See ne2000.c for an example. This cost less
  cpu cycles than setting memory to 0 and then bus_space_write()ing this to
  the I/O port.
- if the adapter is doing scatter/gather DMA, just add an extra preallocated,
  preset to 0 segment at the end. This is almost free in term of CPU cycles.
  See if_tl.c for an example.
- if the adapter is doing DMA from a fixed preallocated buffer (and the mbuf
  chain is copied to this buffer before transmit), just memset the required
  space to 0. Again cost less cycles than setting memory to 0 and copying it
  to the buffer.
- for adapters that autopad themselves, you still add a test in the path.

Now, I don't know if saving these extra CPU cycles is really important or
not. When I did the work on this padding problem, it was decided that the
best place to do this was in the drivers themselves, because it was the most
efficient.

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la difference
--