svn commit: r362113 - in head/sys/netinet: . tcp_stacks

Randall Stewart rrs at FreeBSD.org
Fri Jun 12 19:56:20 UTC 2020


Author: rrs
Date: Fri Jun 12 19:56:19 2020
New Revision: 362113
URL: https://svnweb.freebsd.org/changeset/base/362113

Log:
  So it turns out with the right window scaling you can get the code in all stacks to
  always want to do a window update, even when no data can be sent. Now in
  cases where you are not pacing thats probably ok, you just send an extra
  window update or two. However with bbr (and rack if its paced) every time
  the pacer goes off its going to send a "window update".
  
  Also in testing bbr I have found that if we are not responding to
  data right away we end up staying in startup but incorrectly holding
  a pacing gain of 192 (a loss). This is because the idle window code
  does not restict itself to only work with PROBE_BW. In all other
  states you dont want it doing a PROBE_BW state change.
  
  Sponsored by:	Netflix Inc.
  Differential Revision: 	https://reviews.freebsd.org/D25247

Modified:
  head/sys/netinet/tcp_output.c
  head/sys/netinet/tcp_stacks/bbr.c
  head/sys/netinet/tcp_stacks/rack.c

Modified: head/sys/netinet/tcp_output.c
==============================================================================
--- head/sys/netinet/tcp_output.c	Fri Jun 12 18:41:12 2020	(r362112)
+++ head/sys/netinet/tcp_output.c	Fri Jun 12 19:56:19 2020	(r362113)
@@ -655,7 +655,10 @@ after_sack_rexmit:
 		adv = recwin;
 		if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) {
 			oldwin = (tp->rcv_adv - tp->rcv_nxt);
-			adv -= oldwin;
+			if (adv > oldwin)
+				adv -= oldwin;
+			else
+				adv = 0;
 		} else
 			oldwin = 0;
 

Modified: head/sys/netinet/tcp_stacks/bbr.c
==============================================================================
--- head/sys/netinet/tcp_stacks/bbr.c	Fri Jun 12 18:41:12 2020	(r362112)
+++ head/sys/netinet/tcp_stacks/bbr.c	Fri Jun 12 19:56:19 2020	(r362113)
@@ -8078,7 +8078,7 @@ bbr_restart_after_idle(struct tcp_bbr *bbr, uint32_t c
 			bbr->r_ctl.rc_bbr_hptsi_gain = bbr->r_ctl.rc_startup_pg;
 			bbr->r_ctl.rc_bbr_cwnd_gain = bbr->r_ctl.rc_startup_pg;
 			bbr_log_type_statechange(bbr, cts, __LINE__);
-		} else {
+		} else if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) {
 			bbr_substate_change(bbr, cts, __LINE__, 1);
 		}
 	}
@@ -12000,21 +12000,27 @@ bbr_window_update_needed(struct tcpcb *tp, struct sock
 	 * "adv" is the amount we could increase the window, taking into
 	 * account that we are limited by TCP_MAXWIN << tp->rcv_scale.
 	 */
-	uint32_t adv;
+	int32_t adv;
 	int32_t oldwin;
 
-	adv = min(recwin, TCP_MAXWIN << tp->rcv_scale);
+	adv = recwin;
 	if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) {
 		oldwin = (tp->rcv_adv - tp->rcv_nxt);
-		adv -= oldwin;
+		if (adv > oldwin)
+			adv -= oldwin;
+		else {
+			/* We can't increase the window */
+			adv = 0;
+		}
 	} else
 		oldwin = 0;
 
 	/*
-	 * If the new window size ends up being the same as the old size
-	 * when it is scaled, then don't force a window update.
+	 * If the new window size ends up being the same as or less
+	 * than the old size when it is scaled, then don't force
+	 * a window update.
 	 */
-	if (oldwin >> tp->rcv_scale == (adv + oldwin) >> tp->rcv_scale)
+	if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale)
 		return (0);
 
 	if (adv >= (2 * maxseg) &&

Modified: head/sys/netinet/tcp_stacks/rack.c
==============================================================================
--- head/sys/netinet/tcp_stacks/rack.c	Fri Jun 12 18:41:12 2020	(r362112)
+++ head/sys/netinet/tcp_stacks/rack.c	Fri Jun 12 19:56:19 2020	(r362113)
@@ -12845,18 +12845,24 @@ again:
 		int32_t adv;
 		int oldwin;
 
-		adv = min(recwin, (long)TCP_MAXWIN << tp->rcv_scale);
+		adv = recwin;
 		if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) {
 			oldwin = (tp->rcv_adv - tp->rcv_nxt);
-			adv -= oldwin;
+			if (adv > oldwin)
+			    adv -= oldwin;
+			else {
+				/* We can't increase the window */
+				adv = 0;
+			}
 		} else
 			oldwin = 0;
 
 		/*
-		 * If the new window size ends up being the same as the old
-		 * size when it is scaled, then don't force a window update.
+		 * If the new window size ends up being the same as or less
+		 * than the old size when it is scaled, then don't force
+		 * a window update.
 		 */
-		if (oldwin >> tp->rcv_scale == (adv + oldwin) >> tp->rcv_scale)
+		if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale)
 			goto dontupdate;
 
 		if (adv >= (int32_t)(2 * segsiz) &&


More information about the svn-src-head mailing list