From owner-p4-projects@FreeBSD.ORG Sat Mar 3 18:05:46 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A626E1065670; Sat, 3 Mar 2012 18:05:45 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 683FA106566B for ; Sat, 3 Mar 2012 18:05:45 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 512958FC0A for ; Sat, 3 Mar 2012 18:05:45 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id q23I5jdk007402 for ; Sat, 3 Mar 2012 18:05:45 GMT (envelope-from andre@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id q23I5jWN007399 for perforce@freebsd.org; Sat, 3 Mar 2012 18:05:45 GMT (envelope-from andre@freebsd.org) Date: Sat, 3 Mar 2012 18:05:45 GMT Message-Id: <201203031805.q23I5jWN007399@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to andre@freebsd.org using -f From: Andre Oppermann To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 207318 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 03 Mar 2012 18:05:46 -0000 http://p4web.freebsd.org/@@207318?ac=10 Change 207318 by andre@andre_t61 on 2012/03/03 18:04:56 Add some more retransmit logic. Still incomplete. Affected files ... .. //depot/projects/tcp_new/netinet/tcp_output.c#20 edit Differences ... ==== //depot/projects/tcp_new/netinet/tcp_output.c#20 (text+ko) ==== @@ -835,14 +835,14 @@ * transmit new segment if cwnd allows [output] */ - /* Transmit one more new data if available. */ + /* Transmit one more segment of new data if available. */ if (len > 0 && (len >= tp->snd_mss || dlen == len)) *lenp = len; else *lenp = 0; - /* Do not retransmit if ack didn't move. */ - if (tp->snd_dupack != 3 || tp->snd_dupack != 0) + /* Do not retransmit if ack didn't move snd_una. */ + if (tp->snd_dupack != 3 && tp->snd_dupack != 0) return (0); /* Retransmit one mss or the unacknowledged amount of data. */ @@ -923,9 +923,15 @@ tcp_retransmit_sack(struct tcpcb *tp, struct socket *so, struct tcpopt *to, u_char *opt, int optlen, int *lenp, int rwin, int dlen, int slen, int flags) { - int error = 0, off, rlen = 0, rxmit; + int error = 0, off, rlen = 0; + tcp_seq rxmit; struct tcphdr ths, *th = &ths; + /* Move the retransmit pointer forward if necessary. */ + if (SEQ_LT(tp->snd_rxmit, tp->snd_una)) + tp->snd_rxmit = tp->snd_una; + rxmit = tp->snd_rxmit; + /* * SACK based retransmission RFC3517 * Retransmit over the SACK holes. @@ -934,49 +940,51 @@ * Retransmit only the stuff that was not SACK'ed. * With SACK we may be able to retransmit more than one segment * from different blocks. + * + * duna = flight size + * dlen = available unsent data in send buffer + * len = data available to be sent (within cwnd and wnd) */ do { /* Calculate amount of data we may inject into the pipe (C). */ - rxmit = imax(0, tp->snd_cwnd - tp->snd_pipe); + rlen = imax(0, tp->snd_cwnd - tp->snd_pipe); + + if (rlen == 0) + break; /* No space in pipe for retransmit. */ if (!RB_EMPTY(&tp->snd_sackblocks)) { /* * Get the amount of consequtive data for retransmit. * (C.1) modulo (C.3) */ - if (tp->snd_rxmit == tp->snd_una) + if (SEQ_LEQ(tp->snd_rxmit, tp->snd_una)) rlen = tcp_sack_firsthole(tp, &rxmit); else - rlen = tcp_sack_nextseg(tp, &tp->snd_rxmit, slen); + rlen = tcp_sack_nextseg(tp, &rxmit, slen); /* * If we have nothing to retransmit, see if we can * send some new data. * (C.3) */ - if (rlen == 0) { - if (slen > 0 && (rxmit >= tp->snd_mss || - (rxmit >= slen && dlen == slen))) - *lenp = min(slen, rxmit); - else - *lenp = 0; + if (rlen == 0) break; - } /* * Retransmit what we've got. * (C.1) */ - if (rxmit >= rlen || (rlen > rxmit && rxmit > tp->snd_mss)) + if (rxmit >= rlen || (rlen > rxmit && rxmit > tp->snd_mss)) { rlen = min(rlen, tp->snd_pipe); - else + } else break; - } else if (tp->snd_rxmit == tp->snd_una) + } else if (tp->snd_rxmit == tp->snd_una) { + /* Fallback to normal retransmit. */ rlen = min(tp->snd_mss, SEQ_DELTA(tp->snd_una, tp->snd_nxt)); - else + } else break; /* Fill in headers. */ th->th_win = (u_short)rwin; - th->th_seq = tp->snd_rxmit; + th->th_seq = rxmit; th->th_flags = flags; th->th_ack = tp->rcv_nxt; @@ -992,31 +1000,31 @@ error = tcp_send_segments(tp, &ths, opt, off, &rlen, optlen); SOCKBUF_UNLOCK(&so->so_snd); - /* Start from here the next time. */ - tp->snd_rxmit += rlen; - /* Increase amount of data in the 'pipe' (C.4). */ - tp->snd_pipe += rlen; + if (rlen > 0) { + /* Start from here the next time. */ + tp->snd_rxmit += rlen; - } while (error == 0); + /* Increase amount of data in the 'pipe' (C.4). */ + tp->snd_pipe += rlen; + } - if (rlen > 0) { - } + if (error == 0) { + } - if (error == 0) { - } + if (rlen > 0 || error == 0) { + /* Update last send timestamp. */ + if ((tp->t_flags & TF_TIMESTAMP) && tp->snd_tslast != to->to_tsval) + tp->snd_tslast = to->to_tsval; - if (rlen > 0 || error == 0) { - /* Update last send timestamp. */ - if ((tp->t_flags & TF_TIMESTAMP) && tp->snd_tslast != to->to_tsval) - tp->snd_tslast = to->to_tsval; + /* Last ACK we sent. */ + if (tp->snd_lastack != th->th_ack) + tp->snd_lastack = th->th_ack; + } - /* Last ACK we sent. */ - if (tp->snd_lastack != th->th_ack) - tp->snd_lastack = th->th_ack; - } + if (rlen > 0 && error == 0) { + } - if (rlen > 0 && error == 0) { - } + } while (error == 0); switch (error) { case EPERM: @@ -1039,6 +1047,19 @@ ("%s: unkown error %i", __func__, error)); } + if (slen > 0 && (rlen >= tp->snd_mss || + (rlen >= slen && dlen == slen))) + *lenp = min(slen, rlen); + else + *lenp = 0; + break; + + /* Transmit more new data if available. */ + if (len > 0 && (len >= tp->snd_mss || dlen == len)) + *lenp = len; + else + *lenp = 0; + return (error); } @@ -1399,7 +1420,7 @@ * a rcv_read pointer. */ SOCKBUF_LOCK(&so->so_rcv); - if (so->so_rcv.sb_hiwat - so->so_rcv.sb_cc > 0) + if (so->so_rcv.sb_hiwat - so->so_rcv.sb_cc > 0) // sbspace() delta = SEQ_DELTA(tp->rcv_wnd - so->so_rcv.sb_hiwat, tp->rcv_nxt - so->so_rcv.sb_cc); else