From owner-freebsd-net@FreeBSD.ORG Wed Apr 21 01:20:04 2010 Return-Path: Delivered-To: freebsd-net@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C9147106564A for ; Wed, 21 Apr 2010 01:20:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id B86448FC17 for ; Wed, 21 Apr 2010 01:20:04 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o3L1K46K093596 for ; Wed, 21 Apr 2010 01:20:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o3L1K462093595; Wed, 21 Apr 2010 01:20:04 GMT (envelope-from gnats) Date: Wed, 21 Apr 2010 01:20:04 GMT Message-Id: <201004210120.o3L1K462093595@freefall.freebsd.org> To: freebsd-net@FreeBSD.org From: "Scheffenegger, Richard" Cc: Subject: Re: kern/140597 implement Lost Retransmission Detection X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: "Scheffenegger, Richard" List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Apr 2010 01:20:05 -0000 The following reply was made to PR kern/140597; it has been noted by GNATS. From: "Scheffenegger, Richard" To: , "Lawrence Stewart" Cc: "Biswas, Anumita" 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