[Top][All Lists]

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

Re: [lwip-users] TCP Retransmission when receiving consecutive packets

From: Jens Nielsen
Subject: Re: [lwip-users] TCP Retransmission when receiving consecutive packets
Date: Thu, 20 Mar 2014 16:48:38 +0100
User-agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0


Yes you're probably right, that would be a better solution. What looks like happens next in the wireshark capture is that the interrupt triggered by the retransmission signals your code to read and ack the queued old packet. Then there's an ACK in packet 26 triggering another interrupt that signals your application to read the queued retransmission packet, hence the dup ack in packet 27. And so on, your application is constantly one packet behind the interrupt.

One comment though: I don't know which MCU you're on but I wouldn't assume one interrupt equals one packet. I recently fixed a bug in my application that had a similar setup (interrupt signals with counting semaphore to receive thread, which processed a number of packets equal to the counting semaphore) which didn't cover the case where a second packet is received before the ethernet interrupt has serviced the first packet. My interrupt would only hit once so the second packet was left until the next interrupt.

My solution was to simply try to fetch packets from DMA until it was empty each time my receive thread was woken.

BR /Jens

On 2014-03-20 16:21, Julien Jemine wrote:
Hi Sergio,

I've found this drop packet thing in my driver, however it doesn't seem to break there.
I've had a look at the driver code but I can't find anything...

I am a bit surprised that the ethernet interrupt just raises a flag :

static void eth_notify (ARM_ETH_MAC_EVENT event) {
  /* Send notification on RX event */
  if (event == ARM_ETH_MAC_EVENT_RX_FRAME) {
    rx_event = true;

It seems to imply that calling ethernetif_poll in an IDLE thread will only process on packet even if multiple interrupts have been raised :

void ethernetif_poll (struct netif *netif) {
  struct ethernetif *eth = netif->state;

  if (!eth->phy_ok || eth->link == ARM_ETH_LINK_DOWN) {
  if (rx_event) {
    rx_event = false;
    /* process received ethernet packet */
    ethernetif_input (netif);

I think that an atomic counter and a while loop instead of a flag and a "if" would be more appropriate. Am I wrong ? 
Could that have anything to do with my problem ?

Thanks for your help,


2014-03-20 15:10 GMT+01:00 Sergio R. Caprile <address@hidden>:
Hi Julien.
Yes, there is a TCP retransmission from your host.
I bet that is because when the two packets come in such a close
proximity your Ethernet driver is losing the second one. This, in fact,
can be because there is a problem with the driver itself, or you have a
really low-memory condition and the driver can't find enough memory to
store the packet.
If I would have to hunt this witch, I would start by setting a
breakpoint on the Ethernet driver low_level_input() routine, somewhere
around here:

static struct pbuf *
low_level_input(struct netif *netif)
  /* We allocate a pbuf chain of pbufs from the pool. */
  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);

  if (p != NULL) {
      read data into(q->payload, q->len);
    acknowledge that packet has been read();
  } else {
    drop packet();      <-------------

It actually depends on how the one who actually wrote the driver wanted
to make it difficult for you.
Let me know how it goes.


lwip-users mailing list

lwip-users mailing list

reply via email to

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