Subject: Re: Patch to use a larger TCP initial window for local nets
To: None <tech-net@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-net
Date: 02/27/2003 13:44:06
--8t9RHnE3ZwKMSgU+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Thu, Feb 27, 2003 at 01:42:46PM -0800, Jason R Thorpe wrote:

 > This patch adds makes TCP use a larger initial window (slow-start)
 > for hosts on a local network.  There seems to be little worry of
 > congesting a router when on a local net :-)
 > 
 > This gains about 10% in small-socket-write (1K and 2K) TCP benchmark
 > performance for local net hosts on an ARM platform that Allen Briggs
 > and I are working with.
 > 
 > FWIW, FreeBSD also uses a larger initial window for local networks, so
 > we're clearly not the only ones which have seen a benefit from this :-)
 > 
 > Comments?  I'm particularly interested in how the inet vs inet6 stuff
 > is handled (man, the way we do that is icky).

right, and here is the patch (oops)

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

--8t9RHnE3ZwKMSgU+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=tcp-ss-patch

Index: tcp_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v
retrieving revision 1.162
diff -c -r1.162 tcp_input.c
*** tcp_input.c	2003/02/26 06:31:15	1.162
--- tcp_input.c	2003/02/27 21:36:06
***************
*** 1687,1695 ****
  		 */
  		if (tp->t_flags & TF_SYN_REXMT)
  			tp->snd_cwnd = tp->t_peermss;
! 		else
! 			tp->snd_cwnd = TCP_INITIAL_WINDOW(tcp_init_win,
! 			    tp->t_peermss);
  
  		tcp_rmx_rtt(tp);
  		if (tiflags & TH_ACK) {
--- 1687,1704 ----
  		 */
  		if (tp->t_flags & TF_SYN_REXMT)
  			tp->snd_cwnd = tp->t_peermss;
! 		else {
! 			int ss = tcp_init_win;
! #ifdef INET
! 			if (inp != NULL && in_localaddr(inp->inp_faddr))
! 				ss = tcp_init_win_local;
! #endif
! #ifdef INET6
! 			if (in6p != NULL && in6_localaddr(&in6p->in6p_faddr))
! 				ss = tcp_init_win_local;
! #endif
! 			tp->snd_cwnd = TCP_INITIAL_WINDOW(ss, tp->t_peermss);
! 		}
  
  		tcp_rmx_rtt(tp);
  		if (tiflags & TH_ACK) {
***************
*** 3384,3391 ****
  	 */
  	if (sc->sc_rxtshift)
  		tp->snd_cwnd = tp->t_peermss;
! 	else
! 		tp->snd_cwnd = TCP_INITIAL_WINDOW(tcp_init_win, tp->t_peermss);
  
  	tcp_rmx_rtt(tp);
  	tp->snd_wl1 = sc->sc_irs;
--- 3393,3410 ----
  	 */
  	if (sc->sc_rxtshift)
  		tp->snd_cwnd = tp->t_peermss;
! 	else {
! 		int ss = tcp_init_win;
! #ifdef INET
! 		if (inp != NULL && in_localaddr(inp->inp_faddr))
! 			ss = tcp_init_win_local;
! #endif
! #ifdef INET6
! 		if (in6p != NULL && in6_localaddr(&in6p->in6p_faddr))
! 			ss = tcp_init_win_local;
! #endif
! 		tp->snd_cwnd = TCP_INITIAL_WINDOW(ss, tp->t_peermss);
! 	}
  
  	tcp_rmx_rtt(tp);
  	tp->snd_wl1 = sc->sc_irs;
Index: tcp_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_output.c,v
retrieving revision 1.89
diff -c -r1.89 tcp_output.c
*** tcp_output.c	2003/02/26 06:31:16	1.89
--- tcp_output.c	2003/02/27 21:36:07
***************
*** 561,568 ****
  			 * expected to clock out any data we send --
  			 * slow start to get ack "clock" running again.
  			 */
  			tp->snd_cwnd = min(tp->snd_cwnd,
! 			    TCP_INITIAL_WINDOW(tcp_init_win, txsegsize));
  		}
  	}
  
--- 561,579 ----
  			 * expected to clock out any data we send --
  			 * slow start to get ack "clock" running again.
  			 */
+ 			int ss = tcp_init_win;
+ #ifdef INET
+ 			if (tp->t_inpcb &&
+ 			    in_localaddr(tp->t_inpcb->inp_faddr))
+ 				ss = tcp_init_win_local;
+ #endif
+ #ifdef INET6
+ 			if (tp->t_in6pcb &&
+ 			    in6_localaddr(&tp->t_in6pcb->in6p_faddr))
+ 				ss = tcp_init_win_local;
+ #endif
  			tp->snd_cwnd = min(tp->snd_cwnd,
! 			    TCP_INITIAL_WINDOW(ss, txsegsize));
  		}
  	}
  
Index: tcp_subr.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.138
diff -c -r1.138 tcp_subr.c
*** tcp_subr.c	2003/02/26 06:31:16	1.138
--- tcp_subr.c	2003/02/27 21:36:09
***************
*** 180,186 ****
  int	tcp_do_timestamps = 1;	/* RFC1323 timestamps */
  int	tcp_do_newreno = 0;	/* Use the New Reno algorithms */
  int	tcp_ack_on_push = 0;	/* set to enable immediate ACK-on-PUSH */
! int	tcp_init_win = 1;
  int	tcp_mss_ifmtu = 0;
  #ifdef TCP_COMPAT_42
  int	tcp_compat_42 = 1;
--- 180,187 ----
  int	tcp_do_timestamps = 1;	/* RFC1323 timestamps */
  int	tcp_do_newreno = 0;	/* Use the New Reno algorithms */
  int	tcp_ack_on_push = 0;	/* set to enable immediate ACK-on-PUSH */
! int	tcp_init_win = 1;	/* initial slow start window */
! int	tcp_init_win_local = 4;	/* initial slow start window for local nets */
  int	tcp_mss_ifmtu = 0;
  #ifdef TCP_COMPAT_42
  int	tcp_compat_42 = 1;
Index: tcp_var.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_var.h,v
retrieving revision 1.95
diff -c -r1.95 tcp_var.h
*** tcp_var.h	2003/02/26 06:31:16	1.95
--- tcp_var.h	2003/02/27 21:36:10
***************
*** 590,596 ****
  #endif
  #define	TCPCTL_RSTPPSLIMIT	24	/* RST pps limit */
  #define	TCPCTL_DELACK_TICKS	25	/* # ticks to delay ACK */
! #define	TCPCTL_MAXID		26
  
  #define	TCPCTL_NAMES { \
  	{ 0, 0 }, \
--- 590,597 ----
  #endif
  #define	TCPCTL_RSTPPSLIMIT	24	/* RST pps limit */
  #define	TCPCTL_DELACK_TICKS	25	/* # ticks to delay ACK */
! #define	TCPCTL_INIT_WIN_LOCAL	26	/* initial window for local nets */
! #define	TCPCTL_MAXID		27
  
  #define	TCPCTL_NAMES { \
  	{ 0, 0 }, \
***************
*** 619,624 ****
--- 620,626 ----
  	{ 0, 0 }, \
  	{ "rstppslimit", CTLTYPE_INT }, \
  	{ "delack_ticks", CTLTYPE_INT }, \
+ 	{ "init_win_local", CTLTYPE_INT }, \
  }
  
  #ifdef _KERNEL
***************
*** 635,640 ****
--- 637,643 ----
  extern	int tcp_do_newreno;	/* Use the New Reno algorithms */
  extern	int tcp_mssdflt;	/* default seg size */
  extern	int tcp_init_win;	/* initial window */
+ extern	int tcp_init_win_local;	/* initial window for local nets */
  extern	int tcp_mss_ifmtu;	/* take MSS from interface, not in_maxmtu */
  extern	int tcp_compat_42;	/* work around ancient broken TCP peers */
  extern	int tcp_cwm;		/* enable Congestion Window Monitoring */
***************
*** 683,688 ****
--- 686,692 ----
  	{ 0 },					\
  	{ 1, 0, &tcp_rst_ppslim },		\
  	{ 1, 0, &tcp_delack_ticks },		\
+ 	{ 1, 0, &tcp_init_win_local },		\
  }
  
  #ifdef __NO_STRICT_ALIGNMENT

--8t9RHnE3ZwKMSgU+--