Subject: t_idle revisited
To: None <tech-net@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-net
Date: 09/09/2001 22:36:50
--X1xGqyAVbSpAWs5A
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Folks...

I'm working on some changes (one step at a time) that will allow
us to stop traversing every TCP PCB every 1/2 second (something
that really doesn't scale very well :-)

First step -- compute receive idle time differently.  This is
based on how FreeBSD does it (although I'm still using PR_SLOWHZ,
rather than a finer-grained timer).

Attached is the diff that eliminates tp->t_idle, replacing it
instead with a timestamp and some subtraction.

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

--X1xGqyAVbSpAWs5A
Content-Type: text/plain; charset=us-ascii
Content-Description: t_idle.diff
Content-Disposition: attachment; filename=foo

Index: tcp_input.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/tcp_input.c,v
retrieving revision 1.127
diff -c -r1.127 tcp_input.c
*** tcp_input.c	2001/07/08 16:18:57	1.127
--- tcp_input.c	2001/09/10 05:30:26
***************
*** 1252,1258 ****
  	 * Segment received on connection.
  	 * Reset idle time and keep-alive timer.
  	 */
! 	tp->t_idle = 0;
  	if (TCPS_HAVEESTABLISHED(tp->t_state))
  		TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepidle);
  
--- 1252,1258 ----
  	 * Segment received on connection.
  	 * Reset idle time and keep-alive timer.
  	 */
! 	tp->t_rcvtime = tcp_now;
  	if (TCPS_HAVEESTABLISHED(tp->t_state))
  		TCP_TIMER_ARM(tp, TCPT_KEEP, tcp_keepidle);
  
Index: tcp_output.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/tcp_output.c,v
retrieving revision 1.72
diff -c -r1.72 tcp_output.c
*** tcp_output.c	2001/09/10 04:43:35	1.72
--- tcp_output.c	2001/09/10 05:30:27
***************
*** 467,473 ****
  		    (tcp_cwm_burstsize * txsegsize) +
  		    (tp->snd_nxt - tp->snd_una));
  	} else {
! 		if (idle && tp->t_idle >= tp->t_rxtcur) {
  			/*
  			 * We have been idle for "a while" and no acks are
  			 * expected to clock out any data we send --
--- 467,473 ----
  		    (tcp_cwm_burstsize * txsegsize) +
  		    (tp->snd_nxt - tp->snd_una));
  	} else {
! 		if (idle && (tcp_now - 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 --
Index: tcp_timer.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/tcp_timer.c,v
retrieving revision 1.49
diff -c -r1.49 tcp_timer.c
*** tcp_timer.c	2001/09/10 04:24:25	1.49
--- tcp_timer.c	2001/09/10 05:30:27
***************
*** 220,226 ****
  					goto tpgone;
  			}
  		}
- 		tp->t_idle++;
  		if (tp->t_rtt)
  			tp->t_rtt++;
  tpgone:
--- 220,225 ----
***************
*** 253,259 ****
  					goto tp6gone;
  			}
  		}
- 		tp->t_idle++;
  		if (tp->t_rtt)
  			tp->t_rtt++;
  tp6gone:
--- 252,257 ----
***************
*** 317,323 ****
  	 */
  	case TCPT_2MSL:
  		if (tp->t_state != TCPS_TIME_WAIT &&
! 		    ((tcp_maxidle == 0) || (tp->t_idle <= tcp_maxidle)))
  			TCP_TIMER_ARM(tp, TCPT_2MSL, tcp_keepintvl);
  		else
  			tp = tcp_close(tp);
--- 315,322 ----
  	 */
  	case TCPT_2MSL:
  		if (tp->t_state != TCPS_TIME_WAIT &&
! 		    ((tcp_maxidle == 0) ||
! 		     ((tcp_now - tp->t_rcvtime) <= tcp_maxidle)))
  			TCP_TIMER_ARM(tp, TCPT_2MSL, tcp_keepintvl);
  		else
  			tp = tcp_close(tp);
***************
*** 451,458 ****
  		if (rto < tp->t_rttmin)
  			rto = tp->t_rttmin;
  		if (tp->t_rxtshift == TCP_MAXRXTSHIFT &&
! 		    (tp->t_idle >= tcp_maxpersistidle ||
! 		    tp->t_idle >= rto * tcp_totbackoff)) {
  			tcpstat.tcps_persistdrops++;
  			tp = tcp_drop(tp, ETIMEDOUT);
  			break;
--- 450,457 ----
  		if (rto < tp->t_rttmin)
  			rto = tp->t_rttmin;
  		if (tp->t_rxtshift == TCP_MAXRXTSHIFT &&
! 		    ((tcp_now - tp->t_rcvtime) >= tcp_maxpersistidle ||
! 		    (tcp_now - tp->t_rcvtime) >= rto * tcp_totbackoff)) {
  			tcpstat.tcps_persistdrops++;
  			tp = tcp_drop(tp, ETIMEDOUT);
  			break;
***************
*** 486,492 ****
  		if (so->so_options & SO_KEEPALIVE &&
  		    tp->t_state <= TCPS_CLOSE_WAIT) {
  		    	if ((tcp_maxidle > 0) &&
! 			    (tp->t_idle >= tcp_keepidle + tcp_maxidle))
  				goto dropit;
  			/*
  			 * Send a packet designed to force a response
--- 485,492 ----
  		if (so->so_options & SO_KEEPALIVE &&
  		    tp->t_state <= TCPS_CLOSE_WAIT) {
  		    	if ((tcp_maxidle > 0) &&
! 			    ((tcp_now - tp->t_rcvtime) >=
! 			     tcp_keepidle + tcp_maxidle))
  				goto dropit;
  			/*
  			 * Send a packet designed to force a response
Index: tcp_var.h
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/tcp_var.h,v
retrieving revision 1.83
diff -c -r1.83 tcp_var.h
*** tcp_var.h	2001/09/10 04:24:25	1.83
--- tcp_var.h	2001/09/10 05:30:28
***************
*** 200,206 ****
   * transmit timing stuff.  See below for scale of srtt and rttvar.
   * "Variance" is actually smoothed difference.
   */
! 	short	t_idle;			/* inactivity time */
  	short	t_rtt;			/* round trip time */
  	tcp_seq	t_rtseq;		/* sequence number being timed */
  	short	t_srtt;			/* smoothed round-trip time */
--- 200,206 ----
   * transmit timing stuff.  See below for scale of srtt and rttvar.
   * "Variance" is actually smoothed difference.
   */
! 	uint32_t t_rcvtime;		/* time last segment received */
  	short	t_rtt;			/* round trip time */
  	tcp_seq	t_rtseq;		/* sequence number being timed */
  	short	t_srtt;			/* smoothed round-trip time */

--X1xGqyAVbSpAWs5A--