This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]