This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Odd Length mbufs in Chain
- From: Kelvin Lawson <klawson at ad-holdings dot co dot uk>
- To: ecos-discuss at sources dot redhat dot com
- Date: Wed, 25 Feb 2004 10:55:45 +0000
- Subject: [ECOS] Odd Length mbufs in Chain
Hi All,
I'm getting assert-fails in the ethernet driver due to badly-formatted
eth_drv_sg buffers. The ethernet driver (SMSC 91c111) is being passed an
eth_drv_sg list in which there are odd-length buffers in the middle of
the list. This fails on:
CYG_ASSERT(0 == (len & 1) || (i == (sg_len-1)), "odd length");
From looking at eth_drv_send() it looks like each eth_drv_sg buffer
maps directly to one mbuf in an mbuf chain. Is it required that all
mbufs in a chain are even-length except the last ?
The problem happens if the code does something like:
send (sock, buff1, 60, 0);
send (sock, buff2, 77, 0);
send (sock, buff3, 40, 0);
If each buffer isn't sent immediately then they are chained together,
and then passed to eth_drv_send() in one go. The middle mbuf in the
chain is 77 bytes, and sets off the assert in the ethernet driver.
As a workaround I'm setting TCP_NODELAY to force immediate sends, but
this is only a temporary solution.
I'd like to understand better why this is a problem - Should the
Ethernet driver be allowing chains with odd lengths in the middle, or
should the upper layers be formatting the chains correctly ? I don't
suppose we want the stack to be copying entire chains into a new buffer
to avoid this. (I'm using the FreeBSD stack by the way).
Cheers for any thoughts,
Kelvin.
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss