[ECOS] Odd Length mbufs in Chain

Kelvin Lawson klawson@ad-holdings.co.uk
Wed Feb 25 10:57:00 GMT 2004


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



More information about the Ecos-discuss mailing list