Subject: Re: m_defrag() addition
To: Martin Husemann <martin@duskware.de>
From: Jaromir Dolecek <jdolecek@NetBSD.org>
List: tech-kern
Date: 02/20/2005 18:21:25
On Sun, Feb 20, 2005 at 06:07:13PM +0100, Martin Husemann wrote:
> On Sun, Feb 20, 2005 at 05:26:02PM +0100, Jaromir Dolecek wrote:
> > The function would return new mbuf chain on success or NULL
> > on failure, the old mbuf chain would be freed in either case.
> 
> Why would the old chain be freed on failure?

This is used on error path in driver _start() routine, when
bus_dmamap_load_mbuf() fails. If the dmamap load fails, the driver
is supposed to g/c the mbuf.

Having m_defrag() free the old mbuf chain is usage convenience - the
old mbuf chain would not be used anymore, the driver would free it
otherwise anyway.

> What would be potential reason for such failure besides memory allocation
> problems?

It does happen that a mbuf chain contains too many non-continuous
segments. What is 'too many' depends on ethernet adapter, some of them
have limits on how many DMA segments they can use for transmitted
packets.

The issue occurred for me many times when testing big transfer
(500MB) over 100Mbit/s ethernet network at standard MTU using single
stream. I observed more than 7 such segments for some packets.

If such packet is ignored (rather then defragged and sent), the
communication basically ceases - apparently the network stack would
re-send the packet couple more times, but always in the same
fragmented state. If NIC drops the packet again, no data is ever sent
again on that connection.

Jaromir
-- 
Jaromir Dolecek <jdolecek@NetBSD.org>            http://www.NetBSD.cz/
-=- We can walk our road together if our goals are all the same;     -=-
-=- We can run alone and free if we pursue a different aim.          -=-