From owner-svn-src-head@freebsd.org  Tue Jun  9 21:07:59 2020
Return-Path: <owner-svn-src-head@freebsd.org>
Delivered-To: svn-src-head@mailman.nyi.freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1])
 by mailman.nyi.freebsd.org (Postfix) with ESMTP id 1BB3B33CFA4;
 Tue,  9 Jun 2020 21:07:59 +0000 (UTC)
 (envelope-from rscheff@FreeBSD.org)
Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org
 [IPv6:2610:1c1:1:606c::19:3])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256
 client-signature RSA-PSS (4096 bits) client-digest SHA256)
 (Client CN "mxrelay.nyi.freebsd.org",
 Issuer "Let's Encrypt Authority X3" (verified OK))
 by mx1.freebsd.org (Postfix) with ESMTPS id 49hN4Z74dhz3S3Z;
 Tue,  9 Jun 2020 21:07:58 +0000 (UTC)
 (envelope-from rscheff@FreeBSD.org)
Received: from repo.freebsd.org (repo.freebsd.org
 [IPv6:2610:1c1:1:6068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E92CB1BD64;
 Tue,  9 Jun 2020 21:07:58 +0000 (UTC)
 (envelope-from rscheff@FreeBSD.org)
Received: from repo.freebsd.org ([127.0.1.37])
 by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 059L7wog070121;
 Tue, 9 Jun 2020 21:07:58 GMT (envelope-from rscheff@FreeBSD.org)
Received: (from rscheff@localhost)
 by repo.freebsd.org (8.15.2/8.15.2/Submit) id 059L7wmK070120;
 Tue, 9 Jun 2020 21:07:58 GMT (envelope-from rscheff@FreeBSD.org)
Message-Id: <202006092107.059L7wmK070120@repo.freebsd.org>
X-Authentication-Warning: repo.freebsd.org: rscheff set sender to
 rscheff@FreeBSD.org using -f
From: Richard Scheffenegger <rscheff@FreeBSD.org>
Date: Tue, 9 Jun 2020 21:07:58 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-all@freebsd.org,
 svn-src-head@freebsd.org
Subject: svn commit: r361987 - head/sys/netinet/cc
X-SVN-Group: head
X-SVN-Commit-Author: rscheff
X-SVN-Commit-Paths: head/sys/netinet/cc
X-SVN-Commit-Revision: 361987
X-SVN-Commit-Repository: base
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-head@freebsd.org
X-Mailman-Version: 2.1.33
Precedence: list
List-Id: SVN commit messages for the src tree for head/-current
 <svn-src-head.freebsd.org>
List-Unsubscribe: <https://lists.freebsd.org/mailman/options/svn-src-head>,
 <mailto:svn-src-head-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-head/>
List-Post: <mailto:svn-src-head@freebsd.org>
List-Help: <mailto:svn-src-head-request@freebsd.org?subject=help>
List-Subscribe: <https://lists.freebsd.org/mailman/listinfo/svn-src-head>,
 <mailto:svn-src-head-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Tue, 09 Jun 2020 21:07:59 -0000

Author: rscheff
Date: Tue Jun  9 21:07:58 2020
New Revision: 361987
URL: https://svnweb.freebsd.org/changeset/base/361987

Log:
  Prevent TCP Cubic to abruptly increase cwnd after slow-start
  
  Introducing flags to track the initial Wmax dragging and exit
  from slow-start in TCP Cubic. This prevents sudden jumps in the
  caluclated cwnd by cubic, especially when the flow is application
  limited during slow start (cwnd can not grow as fast as expected).
  The downside is that cubic may remain slightly longer in the
  concave region before starting the convex region beyond Wmax again.
  
  Reviewed by:	chengc_netapp.com, tuexen (mentor)
  Approved by:	tuexen (mentor), rgrimes (mentor, blanket)
  MFC after:	3 weeks
  Sponsored by:	NetApp, Inc.
  Differential Revision:	https://reviews.freebsd.org/D23655

Modified:
  head/sys/netinet/cc/cc_cubic.c

Modified: head/sys/netinet/cc/cc_cubic.c
==============================================================================
--- head/sys/netinet/cc/cc_cubic.c	Tue Jun  9 20:52:35 2020	(r361986)
+++ head/sys/netinet/cc/cc_cubic.c	Tue Jun  9 21:07:58 2020	(r361987)
@@ -90,8 +90,10 @@ struct cubic {
 	unsigned long	max_cwnd;
 	/* cwnd at the previous congestion event. */
 	unsigned long	prev_max_cwnd;
-	/* Number of congestion events. */
-	uint32_t	num_cong_events;
+	/* various flags */
+	uint32_t	flags;
+#define CUBICFLAG_CONG_EVENT	0x00000001	/* congestion experienced */
+#define CUBICFLAG_IN_SLOWSTART	0x00000002	/* in slow start */
 	/* Minimum observed rtt in ticks. */
 	int		min_rtt_ticks;
 	/* Mean observed rtt between congestion epochs. */
@@ -138,9 +140,10 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
 	    (V_tcp_do_rfc3465 && ccv->flags & CCF_ABC_SENTAWND))) {
 		 /* Use the logic in NewReno ack_received() for slow start. */
 		if (CCV(ccv, snd_cwnd) <= CCV(ccv, snd_ssthresh) ||
-		    cubic_data->min_rtt_ticks == TCPTV_SRTTBASE)
+		    cubic_data->min_rtt_ticks == TCPTV_SRTTBASE) {
+			cubic_data->flags |= CUBICFLAG_IN_SLOWSTART;
 			newreno_cc_algo.ack_received(ccv, type);
-		else {
+		} else {
 			if ((ticks_since_cong =
 			    ticks - cubic_data->t_last_cong) < 0) {
 				/*
@@ -150,6 +153,11 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
 				cubic_data->t_last_cong = ticks - INT_MAX;
 			}
 
+			if (cubic_data->flags & CUBICFLAG_IN_SLOWSTART) {
+				cubic_data->flags &= ~CUBICFLAG_IN_SLOWSTART;
+				cubic_data->t_last_cong = ticks;
+				cubic_data->K = 0;
+			}
 			/*
 			 * The mean RTT is used to best reflect the equations in
 			 * the I-D. Using min_rtt in the tf_cwnd calculation
@@ -199,7 +207,7 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
 			 * keep updating our current estimate of the
 			 * max_cwnd.
 			 */
-			if (cubic_data->num_cong_events == 0 &&
+			if (((cubic_data->flags & CUBICFLAG_CONG_EVENT) == 0) &&
 			    cubic_data->max_cwnd < CCV(ccv, snd_cwnd)) {
 				cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
 				cubic_data->K = cubic_k(cubic_data->max_cwnd /
@@ -270,9 +278,10 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
 		if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
 			if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
 				cubic_ssthresh_update(ccv);
-				cubic_data->num_cong_events++;
+				cubic_data->flags |= CUBICFLAG_CONG_EVENT;
 				cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
 				cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
+				cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
 			}
 			ENTER_RECOVERY(CCV(ccv, t_flags));
 		}
@@ -281,10 +290,11 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
 	case CC_ECN:
 		if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
 			cubic_ssthresh_update(ccv);
-			cubic_data->num_cong_events++;
+			cubic_data->flags |= CUBICFLAG_CONG_EVENT;
 			cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
 			cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
 			cubic_data->t_last_cong = ticks;
+			cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
 			CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
 			ENTER_CONGRECOVERY(CCV(ccv, t_flags));
 		}
@@ -299,7 +309,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
 		 * congestion.
 		 */
 		if (CCV(ccv, t_rxtshift) >= 2) {
-			cubic_data->num_cong_events++;
+			cubic_data->flags |= CUBICFLAG_CONG_EVENT;
 			cubic_data->t_last_cong = ticks;
 		}
 		break;
@@ -442,7 +452,7 @@ cubic_ssthresh_update(struct cc_var *ccv)
 	 * On the first congestion event, set ssthresh to cwnd * 0.5, on
 	 * subsequent congestion events, set it to cwnd * beta.
 	 */
-	if (cubic_data->num_cong_events == 0)
+	if ((cubic_data->flags & CUBICFLAG_CONG_EVENT) == 0)
 		ssthresh = CCV(ccv, snd_cwnd) >> 1;
 	else
 		ssthresh = ((uint64_t)CCV(ccv, snd_cwnd) *