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--