svn commit: r211871 - stable/7/sys/netinet

Andre Oppermann andre at FreeBSD.org
Fri Aug 27 10:16:32 UTC 2010


Author: andre
Date: Fri Aug 27 10:16:32 2010
New Revision: 211871
URL: http://svn.freebsd.org/changeset/base/211871

Log:
  MFC r211464:
  
    If a TCP connection has been idle for one retransmit timeout or more
    it must reset its congestion window back to the initial window.
  
    RFC3390 has increased the initial window from 1 segment to up to
    4 segments.
  
    The initial window increase of RFC3390 wasn't reflected into the
    restart window which remained at its original defaults of 4 segments
    for local and 1 segment for all other connections.  Both values are
    controllable through sysctl net.inet.tcp.local_slowstart_flightsize
    and net.inet.tcp.slowstart_flightsize.
  
    The increase helps TCP's slow start algorithm to open up the congestion
    window much faster.
  
    Reviewed by:	lstewart
    MFC after:	1 week

Modified:
  stable/7/sys/netinet/tcp_input.c
  stable/7/sys/netinet/tcp_output.c
  stable/7/sys/netinet/tcp_var.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/netinet/tcp_input.c
==============================================================================
--- stable/7/sys/netinet/tcp_input.c	Fri Aug 27 10:15:45 2010	(r211870)
+++ stable/7/sys/netinet/tcp_input.c	Fri Aug 27 10:16:32 2010	(r211871)
@@ -123,7 +123,7 @@ static int tcp_do_rfc3042 = 1;
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_RW,
     &tcp_do_rfc3042, 0, "Enable RFC 3042 (Limited Transmit)");
 
-static int tcp_do_rfc3390 = 1;
+int tcp_do_rfc3390 = 1;
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_RW,
     &tcp_do_rfc3390, 0,
     "Enable RFC 3390 (Increasing TCP's Initial Congestion Window)");

Modified: stable/7/sys/netinet/tcp_output.c
==============================================================================
--- stable/7/sys/netinet/tcp_output.c	Fri Aug 27 10:15:45 2010	(r211870)
+++ stable/7/sys/netinet/tcp_output.c	Fri Aug 27 10:16:32 2010	(r211871)
@@ -127,7 +127,7 @@ tcp_output(struct tcpcb *tp)
 {
 	struct socket *so = tp->t_inpcb->inp_socket;
 	long len, recwin, sendwin;
-	int off, flags, error;
+	int off, flags, error, rw;
 	struct mbuf *m;
 	struct ip *ip = NULL;
 	struct ipovly *ipov = NULL;
@@ -163,23 +163,34 @@ tcp_output(struct tcpcb *tp)
 	idle = (tp->t_flags & TF_LASTIDLE) || (tp->snd_max == tp->snd_una);
 	if (idle && (ticks - (int)tp->t_rcvtime) >= tp->t_rxtcur) {
 		/*
-		 * We have been idle for "a while" and no acks are
-		 * expected to clock out any data we send --
-		 * slow start to get ack "clock" running again.
+		 * If we've been idle for more than one retransmit
+		 * timeout the old congestion window is no longer
+		 * current and we have to reduce it to the restart
+		 * window before we can transmit again.
 		 *
-		 * Set the slow-start flight size depending on whether
-		 * this is a local network or not.
+		 * The restart window is the initial window or the last
+		 * CWND, whichever is smaller.
+		 * 
+		 * This is done to prevent us from flooding the path with
+		 * a full CWND at wirespeed, overloading router and switch
+		 * buffers along the way.
+		 *
+		 * See RFC5681 Section 4.1. "Restarting Idle Connections".
 		 */
-		int ss = ss_fltsz;
+		if (tcp_do_rfc3390)
+			rw = min(4 * tp->t_maxseg,
+				 max(2 * tp->t_maxseg, 4380));
 #ifdef INET6
-		if (isipv6) {
-			if (in6_localaddr(&tp->t_inpcb->in6p_faddr))
-				ss = ss_fltsz_local;
-		} else
-#endif /* INET6 */
-		if (in_localaddr(tp->t_inpcb->inp_faddr))
-			ss = ss_fltsz_local;
-		tp->snd_cwnd = tp->t_maxseg * ss;
+		else if ((isipv6 ? in6_localaddr(&tp->t_inpcb->in6p_faddr) :
+			  in_localaddr(tp->t_inpcb->inp_faddr)))
+#else
+		else if (in_localaddr(tp->t_inpcb->inp_faddr))
+#endif
+			rw = ss_fltsz_local * tp->t_maxseg;
+		else
+			rw = ss_fltsz * tp->t_maxseg;
+
+		tp->snd_cwnd = min(rw, tp->snd_cwnd);
 	}
 	tp->t_flags &= ~TF_LASTIDLE;
 	if (idle) {

Modified: stable/7/sys/netinet/tcp_var.h
==============================================================================
--- stable/7/sys/netinet/tcp_var.h	Fri Aug 27 10:15:45 2010	(r211870)
+++ stable/7/sys/netinet/tcp_var.h	Fri Aug 27 10:16:32 2010	(r211871)
@@ -513,6 +513,7 @@ extern	int tcp_mssdflt;	/* XXX */
 extern	int tcp_minmss;
 extern	int tcp_delack_enabled;
 extern	int tcp_do_newreno;
+extern	int tcp_do_rfc3390;
 extern	int path_mtu_discovery;
 extern	int ss_fltsz;
 extern	int ss_fltsz_local;


More information about the svn-src-stable-7 mailing list