kern/140597 implement Lost Retransmission Detection

Scheffenegger, Richard rs at netapp.com
Wed Apr 21 01:20:05 UTC 2010


The following reply was made to PR kern/140597; it has been noted by GNATS.

From: "Scheffenegger, Richard" <rs at netapp.com>
To: <bug-followup at freebsd.org>, "Lawrence Stewart" <lastewart at swin.edu.au>
Cc: "Biswas, Anumita" <Anumita.Biswas at netapp.com>
Subject: Re: kern/140597 implement Lost Retransmission Detection
Date: Wed, 21 Apr 2010 02:16:01 +0100

 I found a small oversight (bug) in my earlier simple fix. If we had sent
 out multiple holes already, all of which get (partially) lost in the
 retransmission again, the original simple patch would only work for the
 very first hole. So, subsequent holes would not get re-sent, unless
 another ACK (SACK) would be received - however, seeing more SACKs
 becomes less likely the more loss is expirienced.
 
 This is a updated patch diff, which accounts for that case as well - but
 at the cost of O(n) time, instead of O(c).
 
 (Just check all holes from the hint backwards to the head, if any
 already fully resent hole needs to be reset, instead of only the first
 one - which might go away during subsequent processing in the original
 patch).
 
 
 
 diff -u netinet.orig/tcp_output.c netinet/tcp_output.c
 --- netinet.orig/tcp_output.c   2009-10-25 02:10:29.000000000 +0100
 +++ netinet/tcp_output.c        2010-04-02 16:55:14.000000000 +0200
 @@ -953,6 +953,10 @@
         } else {
                 th->th_seq =3D htonl(p->rxmit);
                 p->rxmit +=3D len;
 +               /* lost again detection */
 +               if (SEQ_GEQ(p->rxmit, p->end)) {
 +                       p->rxmit =3D tp->snd_nxt;
 +               }
                 tp->sackhint.sack_bytes_rexmit +=3D len;
         }
         th->th_ack =3D htonl(tp->rcv_nxt);
 diff -u netinet.orig/tcp_sack.c netinet.simple_mod/tcp_sack.c
 --- netinet.orig/tcp_sack.c     2009-10-25 02:10:29.000000000 +0100
 +++ netinet/tcp_sack.c          2010-04-21 00:48:23.000000000 +0200
 @@ -508,7 +508,9 @@
                         if (SEQ_GEQ(sblkp->end, cur->end)) {
                                 /* Move end of hole backward. */
                                 cur->end =3D sblkp->start;
 -                               cur->rxmit =3D SEQ_MIN(cur->rxmit,
 cur->end);
 +                               if (SEQ_GEQ(cur->rxmit, cur->end)) {
 +                                       cur->rxmit =3D tp->snd_nxt;
 +                               }
                         } else {
                                 /*
                                  * ACKs some data in middle of a hole;
 need
 @@ -524,8 +526,9 @@
                                                     - temp->start);
                                         }
                                         cur->end =3D sblkp->start;
 -                                       cur->rxmit =3D =
 SEQ_MIN(cur->rxmit,
 -                                           cur->end);
 +                                       if (SEQ_GEQ(cur->rxmit,
 cur->end)) {
 +                                               cur->rxmit =3D
 tp->snd_nxt;
 +                                       }
                                 }
                         }
                 }
 @@ -540,6 +543,15 @@
                 else
                         sblkp--;
         }
 +       /* retransmission lost again - then restart */
 +       if ((temp =3D tp->sackhint.nexthole) !=3D NULL) {
 +               do {
 +                       if (SEQ_GT(tp->snd_fack, temp->rxmit)) {
 +                               temp->rxmit =3D temp->start;
 +                               tp->sackhint.nexthole =3D temp;
 +                       }
 +               } while ((temp =3D TAILQ_PREV(temp, sackhole_head,
 scblink)) !=3D NULL);
 +       }
  }
 
  /*
 
 
 
 
 Richard Scheffenegger
 
 =20
 


More information about the freebsd-net mailing list