lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [bug #36380] unsent_oversize mismatch in 1.4.1RC1


From: Marco Jakobs
Subject: [lwip-devel] [bug #36380] unsent_oversize mismatch in 1.4.1RC1
Date: Sat, 05 May 2012 10:36:00 +0000
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0

Follow-up Comment #11, bug #36380 (project lwip):

Dear Simon,

i've spent a part of the night going through the SAM7_EMAC.c for the
transmissions. The number of blocked Tx Buffers pointed me there (There should
never be a "lost" buffer if Tx is good).

As you've much more experience, i'd share my thoughts here ...

<THEORY>
The "lEMACSend" function writes the pbuf in the EMAC transmit buffers and then
sets the "TSTART" flag of the EMAC to start the transmission. The transmission
end is signalled by the ISR, freeing the used EMAC buffers in the desription
pointers list.

However, the lEMACSend only checks if the buffer space is full - when the
potential buffer for the next write is tagged as "unused" (AT91C_TRANSMIT_OK
auf 0) this block is not yet sent - in this case it does some vTaskDelay until
the block has been transmitted to continue the writing of the actual pBufs to
the EMAC buffers. In case that a timeout occurs here, i'll get the "Buffer
blocked" logger output: Then an EMAC buffer tagged for transmission is never
transmitted (which should not occur) and all Buffers are reset to prevent a
permanent blocked Ethernet transmission.

The thought is: It should normally *NEVER* come to a "not transmitted" block.

After a pbuf is written, the transmission is started by setting the "TSTART"
bit in the EMAC Network Control Register (NCR) and the lEMACSend will be left.
If lEMACSend is called the next time, it will write the new pbuf in the next
free buffers and set the TSTART again (which is allowed be be done during a
still ongoing transmission).

My theory here: If a transmission is ongoing (large packet) and the first
(small) pbuf is written, TSTART is set. The EMAC should do this new
transmission right after the large one has finished. But if the input from
LwIP is so fast that a *third* (small) packet will be written during the first
large one is still in transmission and the second small one is queued (TSTART
is still set because of the second packet waiting), the third packet will be
written in the buffer, but as the TSTART is still set, this packet will never
be transmitted because the EMAC finishes the transmission after packet 2 (the
TSTART bit can not count waiting packets as it's just a single flag). As the
pointer to the descriptors were not updated, the next packet (number four)
will send out packet three (when TSTART is set again by packet four) -
however, we have always one "unsent" packet in the EMAC buffers.

Having this behaviour repeated over the time, we may "sum up" some unsent
packets until there is no space left on a lEMACSend call - which will free all
blocks and trigger the logger message i see.
</THEORY>

I've just added these lines right at the start of lEMACSend:

while (AT91C_BASE_EMAC->EMAC_TSR & AT91C_EMAC_TSTART)
{
  vTaskDelay(1);
}

Which prevents the writing of any new pbuf as long as the TSTART bit is still
set (assuming that there is an ongoing transmission AND another block waiting
to being transmitted). The AT91SAM7X datasheet unfortunately does not tell me
when TSTART will be reset, but i assume this will be happen when the
transmission has started. The delay should make sure that no pbuf is written
to the EMAC Tx buffers as long as the transmission event can't be told to the
EMAC.

With this enhancement i was not able to cause the "Tx Buffers Blocked" error
message again and the system seems much more stable on high TCP traffic. I
have seem some seldom data aborts putting a high Tx load for a pretty long
time.

Changing my delay above to just

while (AT91C_BASE_EMAC->EMAC_TSR & AT91C_EMAC_TSTART);

and was also not able to see this daborts, as i'm now blocking all lower
priorities tasks which may continue to feed the LwIP with more data while the
(high priority) EMAC task is waiting for the oppertunity to transmit.

Any comments are appreciated here - what is the right way to solve the output
problem? How do you this in your proper running project?

I'll test again with the TCP_OVERSIZE set ...



    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?36380>

_______________________________________________
  Nachricht gesendet von/durch Savannah
  http://savannah.nongnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]