lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] TCP spurious Retransmission and Dup Ack issue


From: Axel Lin
Subject: Re: [lwip-users] TCP spurious Retransmission and Dup Ack issue
Date: Sun, 15 Jan 2017 23:20:25 +0800

2017-01-09 21:56 GMT+08:00 Sergio R. Caprile <address@hidden>:
> Your sequence number is jumping backwards.
> Most common causes are either one of your apps is trashing memory of you
> have a bad DMA driver.

Hi Sergio,

Thanks for your comments.
It seems every time before run into tcp-out-of-order issue, the code
run in below path:
I'm wondering if anything unusual in below code path?

Note, I have LWIP_NETIF_TX_SINGLE_PBUF set, so TCP_WRITE_FLAG_COPY is set:
I also add some run-time value of related variables in below:

In tcp_write():

 468     oversize = pcb->unsent_oversize;
//oversize=0, pcb->unsent_oversize=0
 469     if (oversize > 0) {
 470       LWIP_ASSERT("inconsistent oversize vs. space",
oversize_used <= space);
 471       seg = last_unsent;
 472       oversize_used = LWIP_MIN(space, LWIP_MIN(oversize, len));
 473       pos += oversize_used;
 474       oversize -= oversize_used;
 475       space -= oversize_used;
 476     }
 477     /* now we are either finished or oversize is zero */
 478     LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0)
|| (pos == len));
 479 #endif /* TCP_OVERSIZE */
 480
 481     /*
 482      * Phase 2: Chain a new pbuf to the end of pcb->unsent.
 483      *
 484      * As an exception when NOT copying the data, if the given data buffer
 485      * directly follows the last unsent data buffer in memory,
extend the last
 486      * ROM pbuf reference to the buffer, thus saving a ROM pbuf allocation.
 487      *
 488      * We don't extend segments containing SYN/FIN flags or options
 489      * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at
 490      * the end.
 491      */
 492     if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
// pos=0, len=58, space=1148, last_unsent->len=4
 493       u16_t seglen = space < len - pos ? space : len - pos;
// seglen=58
 494       seg = last_unsent;
 495
 496       /* Create a pbuf with a copy or reference to seglen bytes. We
 497        * can use PBUF_RAW here since the data appears in the middle of
 498        * a segment. A header will never be prepended. */
 499       if (apiflags & TCP_WRITE_FLAG_COPY) {
 500         /* Data is copied */
 501         if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen,
space, &oversize, pcb, apiflags, 1)) == NULL) {     // oversize
becomes 1090 here
 502           LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
 503                       ("tcp_write : could not allocate memory for
pbuf copy size %"U16_F"\n",
 504                        seglen));
 505           goto memerr;
 506         }
 507 #if TCP_OVERSIZE_DBGCHECK
 508         last_unsent->oversize_left += oversize;
 509 #endif /* TCP_OVERSIZE_DBGCHECK */
 510         TCP_DATA_COPY2(concat_p->payload, (const u8_t*)arg + pos,
seglen, &concat_chksum, &concat_chksum_swapped);
 511 #if TCP_CHECKSUM_ON_COPY
 512         concat_chksummed += seglen;
 513 #endif /* TCP_CHECKSUM_ON_COPY */
 514         queuelen += pbuf_clen(concat_p);

And then I got below message latter after above code path.
tcp_write: too long queue 24 (max 24)

I also upload the wireshark log in below link for reference:
https://www.dropbox.com/s/16slydot7rx221f/lwip_tcp_out_of_order.pcapng?dl=0
lwip device is running at 192.168.0.101 8080 port.

Thanks,
Axel



reply via email to

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