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

On Sun, Sep 09, 2001 at 10:36:50PM -0700, Jason R Thorpe wrote:

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

...and again, this time w/ t_rtt fixed up, too.

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

--CNK/L7dwKXQ4Ub8J
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 06:11:14
***************
*** 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);
  
***************
*** 1306,1314 ****
  				if (opti.ts_present && opti.ts_ecr)
  					tcp_xmit_timer(tp,
  					  TCP_TIMESTAMP(tp) - opti.ts_ecr + 1);
! 				else if (tp->t_rtt &&
  				    SEQ_GT(th->th_ack, tp->t_rtseq))
! 					tcp_xmit_timer(tp, tp->t_rtt);
  				acked = th->th_ack - tp->snd_una;
  				tcpstat.tcps_rcvackpack++;
  				tcpstat.tcps_rcvackbyte += acked;
--- 1306,1315 ----
  				if (opti.ts_present && opti.ts_ecr)
  					tcp_xmit_timer(tp,
  					  TCP_TIMESTAMP(tp) - opti.ts_ecr + 1);
! 				else if (tp->t_rtttime &&
  				    SEQ_GT(th->th_ack, tp->t_rtseq))
! 					tcp_xmit_timer(tp,
! 					tcp_now - tp->t_rtttime);
  				acked = th->th_ack - tp->snd_una;
  				tcpstat.tcps_rcvackpack++;
  				tcpstat.tcps_rcvackbyte += acked;
***************
*** 1459,1466 ****
  			 * if we didn't have to retransmit the SYN,
  			 * use its rtt as our initial srtt & rtt var.
  			 */
! 			if (tp->t_rtt)
! 				tcp_xmit_timer(tp, tp->t_rtt);
  		} else
  			tp->t_state = TCPS_SYN_RECEIVED;
  
--- 1460,1467 ----
  			 * if we didn't have to retransmit the SYN,
  			 * use its rtt as our initial srtt & rtt var.
  			 */
! 			if (tp->t_rtttime)
! 				tcp_xmit_timer(tp, tcp_now - tp->t_rtttime);
  		} else
  			tp->t_state = TCPS_SYN_RECEIVED;
  
***************
*** 1789,1795 ****
  					tp->snd_ssthresh = win * tp->t_segsz;
  					tp->snd_recover = tp->snd_max;
  					TCP_TIMER_DISARM(tp, TCPT_REXMT);
! 					tp->t_rtt = 0;
  					tp->snd_nxt = th->th_ack;
  					tp->snd_cwnd = tp->t_segsz;
  					(void) tcp_output(tp);
--- 1790,1796 ----
  					tp->snd_ssthresh = win * tp->t_segsz;
  					tp->snd_recover = tp->snd_max;
  					TCP_TIMER_DISARM(tp, TCPT_REXMT);
! 					tp->t_rtttime = 0;
  					tp->snd_nxt = th->th_ack;
  					tp->snd_cwnd = tp->t_segsz;
  					(void) tcp_output(tp);
***************
*** 1849,1856 ****
  		 */
  		if (opti.ts_present && opti.ts_ecr)
  			tcp_xmit_timer(tp, TCP_TIMESTAMP(tp) - opti.ts_ecr + 1);
! 		else if (tp->t_rtt && SEQ_GT(th->th_ack, tp->t_rtseq))
! 			tcp_xmit_timer(tp,tp->t_rtt);
  
  		/*
  		 * If all outstanding data is acked, stop retransmit
--- 1850,1857 ----
  		 */
  		if (opti.ts_present && opti.ts_ecr)
  			tcp_xmit_timer(tp, TCP_TIMESTAMP(tp) - opti.ts_ecr + 1);
! 		else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq))
! 			tcp_xmit_timer(tp, tcp_now - tp->t_rtttime);
  
  		/*
  		 * If all outstanding data is acked, stop retransmit
***************
*** 2425,2437 ****
  void
  tcp_xmit_timer(tp, rtt)
  	struct tcpcb *tp;
! 	short rtt;
  {
! 	short delta;
! 	short rttmin;
  
  	tcpstat.tcps_rttupdated++;
- 	--rtt;
  	if (tp->t_srtt != 0) {
  		/*
  		 * srtt is stored as fixed point with 3 bits after the
--- 2426,2436 ----
  void
  tcp_xmit_timer(tp, rtt)
  	struct tcpcb *tp;
! 	uint32_t rtt;
  {
! 	int32_t delta;
  
  	tcpstat.tcps_rttupdated++;
  	if (tp->t_srtt != 0) {
  		/*
  		 * srtt is stored as fixed point with 3 bits after the
***************
*** 2467,2473 ****
  		tp->t_srtt = rtt << (TCP_RTT_SHIFT + 2);
  		tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT + 2 - 1);
  	}
! 	tp->t_rtt = 0;
  	tp->t_rxtshift = 0;
  
  	/*
--- 2466,2472 ----
  		tp->t_srtt = rtt << (TCP_RTT_SHIFT + 2);
  		tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT + 2 - 1);
  	}
! 	tp->t_rtttime = 0;
  	tp->t_rxtshift = 0;
  
  	/*
***************
*** 2481,2491 ****
  	 * statistical, we have to test that we don't drop below
  	 * the minimum feasible timer (which is 2 ticks).
  	 */
! 	if (tp->t_rttmin > rtt + 2)
! 		rttmin = tp->t_rttmin;
! 	else
! 		rttmin = rtt + 2;
! 	TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), rttmin, TCPTV_REXMTMAX);
  	
  	/*
  	 * We received an ack for a packet that wasn't retransmitted;
--- 2480,2487 ----
  	 * statistical, we have to test that we don't drop below
  	 * the minimum feasible timer (which is 2 ticks).
  	 */
! 	TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp),
! 	    max(tp->t_rttmin, rtt + 2), TCPTV_REXMTMAX);
  	
  	/*
  	 * We received an ack for a packet that wasn't retransmitted;
***************
*** 2519,2525 ****
  		 * offset in tcp_output().
  		 */
  		TCP_TIMER_DISARM(tp, TCPT_REXMT);
! 	        tp->t_rtt = 0;
  	        tp->snd_nxt = th->th_ack;
  		/*
  		 * Set snd_cwnd to one segment beyond ACK'd offset.  snd_una
--- 2515,2521 ----
  		 * offset in tcp_output().
  		 */
  		TCP_TIMER_DISARM(tp, TCPT_REXMT);
! 	        tp->t_rtttime = 0;
  	        tp->snd_nxt = th->th_ack;
  		/*
  		 * Set snd_cwnd to one segment beyond ACK'd offset.  snd_una
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 06:11:15
***************
*** 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 --
***************
*** 938,945 ****
  			 * Time this transmission if not a retransmission and
  			 * not currently timing anything.
  			 */
! 			if (tp->t_rtt == 0) {
! 				tp->t_rtt = 1;
  				tp->t_rtseq = startseq;
  				tcpstat.tcps_segstimed++;
  			}
--- 938,945 ----
  			 * Time this transmission if not a retransmission and
  			 * not currently timing anything.
  			 */
! 			if (tp->t_rtttime == 0) {
! 				tp->t_rtttime = tcp_now;
  				tp->t_rtseq = startseq;
  				tcpstat.tcps_segstimed++;
  			}
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 06:11:15
***************
*** 220,228 ****
  					goto tpgone;
  			}
  		}
- 		tp->t_idle++;
- 		if (tp->t_rtt)
- 			tp->t_rtt++;
  tpgone:
  		;
  	}
--- 220,225 ----
***************
*** 253,261 ****
  					goto tp6gone;
  			}
  		}
- 		tp->t_idle++;
- 		if (tp->t_rtt)
- 			tp->t_rtt++;
  tp6gone:
  		;
  	}
--- 250,255 ----
***************
*** 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);
--- 311,318 ----
  	 */
  	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);
***************
*** 391,397 ****
  		/*
  		 * If timing a segment in this window, stop the timer.
  		 */
! 		tp->t_rtt = 0;
  		/*
  		 * Remember if we are retransmitting a SYN, because if
  		 * we do, set the initial congestion window must be set
--- 386,392 ----
  		/*
  		 * If timing a segment in this window, stop the timer.
  		 */
! 		tp->t_rtttime = 0;
  		/*
  		 * Remember if we are retransmitting a SYN, because if
  		 * we do, set the initial congestion window must be set
***************
*** 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;
--- 446,453 ----
  		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
--- 481,488 ----
  		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 06:11:16
***************
*** 136,142 ****
  	u_int	t_timer[TCPT_NTIMERS];	/* tcp timers */
  	short	t_state;		/* state of this connection */
  	short	t_rxtshift;		/* log(2) of rexmt exp. backoff */
! 	short	t_rxtcur;		/* current retransmit value */
  	short	t_dupacks;		/* consecutive dup acks recd */
  	u_short	t_peermss;		/* peer's maximum segment size */
  	u_short	t_ourmss;		/* our's maximum segment size */
--- 136,142 ----
  	u_int	t_timer[TCPT_NTIMERS];	/* tcp timers */
  	short	t_state;		/* state of this connection */
  	short	t_rxtshift;		/* log(2) of rexmt exp. backoff */
! 	uint32_t t_rxtcur;		/* current retransmit value */
  	short	t_dupacks;		/* consecutive dup acks recd */
  	u_short	t_peermss;		/* peer's maximum segment size */
  	u_short	t_ourmss;		/* our's maximum segment size */
***************
*** 200,211 ****
   * 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 */
! 	short	t_rttvar;		/* variance in round-trip time */
! 	short	t_rttmin;		/* minimum rtt allowed */
  	u_long	max_sndwnd;		/* largest window peer has offered */
  
  /* out-of-band data */
--- 200,211 ----
   * transmit timing stuff.  See below for scale of srtt and rttvar.
   * "Variance" is actually smoothed difference.
   */
! 	uint32_t t_rcvtime;		/* time last segment received */
! 	uint32_t t_rtttime;		/* time we started measuring rtt */
  	tcp_seq	t_rtseq;		/* sequence number being timed */
! 	int32_t	t_srtt;			/* smoothed round-trip time */
! 	int32_t	t_rttvar;		/* variance in round-trip time */
! 	uint32_t t_rttmin;		/* minimum rtt allowed */
  	u_long	max_sndwnd;		/* largest window peer has offered */
  
  /* out-of-band data */
***************
*** 702,708 ****
  int	 tcp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
  int	 tcp_usrreq __P((struct socket *,
  	    int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *));
! void	 tcp_xmit_timer __P((struct tcpcb *, int));
  tcp_seq	 tcp_new_iss __P((struct tcpcb *, tcp_seq));
  tcp_seq  tcp_new_iss1 __P((void *, void *, u_int16_t, u_int16_t, size_t,
  	    tcp_seq));
--- 702,708 ----
  int	 tcp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
  int	 tcp_usrreq __P((struct socket *,
  	    int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *));
! void	 tcp_xmit_timer __P((struct tcpcb *, uint32_t));
  tcp_seq	 tcp_new_iss __P((struct tcpcb *, tcp_seq));
  tcp_seq  tcp_new_iss1 __P((void *, void *, u_int16_t, u_int16_t, size_t,
  	    tcp_seq));

--CNK/L7dwKXQ4Ub8J--