aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Oppermann <andre@FreeBSD.org>2006-02-16 19:38:07 +0000
committerAndre Oppermann <andre@FreeBSD.org>2006-02-16 19:38:07 +0000
commiteaf80179e2036deb396c6988bfacc9975d49ded0 (patch)
tree50085f7cd5f6a0c2d314a7e5e7a2100f076b6b44
parente3989d3ebf0821b15bb0f0cc89b381ecc4f63dbf (diff)
downloadsrc-eaf80179e2036deb396c6988bfacc9975d49ded0.tar.gz
src-eaf80179e2036deb396c6988bfacc9975d49ded0.zip
Have TCP Inflight disable itself if the RTT is below a certain
threshold. Inflight doesn't make sense on a LAN as it has trouble figuring out the maximal bandwidth because of the coarse tick granularity. The sysctl net.inet.tcp.inflight.rttthresh specifies the threshold in milliseconds below which inflight will disengage. It defaults to 10ms. Tested by: Joao Barros <joao.barros-at-gmail.com>, Rich Murphey <rich-at-whiteoaklabs.com> Sponsored by: TCP/IP Optimization Fundraise 2005
Notes
Notes: svn path=/head/; revision=155767
-rw-r--r--sys/netinet/tcp_input.c10
-rw-r--r--sys/netinet/tcp_reass.c10
-rw-r--r--sys/netinet/tcp_subr.c8
-rw-r--r--sys/netinet/tcp_timer.h3
-rw-r--r--sys/netinet/tcp_timewait.c8
-rw-r--r--sys/netinet/tcp_var.h1
6 files changed, 38 insertions, 2 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index e71b6bdd0853..d50333be6a86 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1193,10 +1193,16 @@ after_listen:
*/
if ((to.to_flags & TOF_TS) != 0 &&
to.to_tsecr) {
+ if (!tp->t_rttlow ||
+ tp->t_rttlow > ticks - to.to_tsecr)
+ tp->t_rttlow = ticks - to.to_tsecr;
tcp_xmit_timer(tp,
ticks - to.to_tsecr + 1);
} else if (tp->t_rtttime &&
SEQ_GT(th->th_ack, tp->t_rtseq)) {
+ if (!tp->t_rttlow ||
+ tp->t_rttlow > ticks - tp->t_rtttime)
+ tp->t_rttlow = ticks - tp->t_rtttime;
tcp_xmit_timer(tp,
ticks - tp->t_rtttime);
}
@@ -2077,8 +2083,12 @@ process_ACK:
*/
if ((to.to_flags & TOF_TS) != 0 &&
to.to_tsecr) {
+ if (!tp->t_rttlow || tp->t_rttlow > ticks - to.to_tsecr)
+ tp->t_rttlow = ticks - to.to_tsecr;
tcp_xmit_timer(tp, ticks - to.to_tsecr + 1);
} else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) {
+ if (!tp->t_rttlow || tp->t_rttlow > ticks - tp->t_rtttime)
+ tp->t_rttlow = ticks - tp->t_rtttime;
tcp_xmit_timer(tp, ticks - tp->t_rtttime);
}
tcp_xmit_bandwidth_limit(tp, th->th_ack);
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index e71b6bdd0853..d50333be6a86 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -1193,10 +1193,16 @@ after_listen:
*/
if ((to.to_flags & TOF_TS) != 0 &&
to.to_tsecr) {
+ if (!tp->t_rttlow ||
+ tp->t_rttlow > ticks - to.to_tsecr)
+ tp->t_rttlow = ticks - to.to_tsecr;
tcp_xmit_timer(tp,
ticks - to.to_tsecr + 1);
} else if (tp->t_rtttime &&
SEQ_GT(th->th_ack, tp->t_rtseq)) {
+ if (!tp->t_rttlow ||
+ tp->t_rttlow > ticks - tp->t_rtttime)
+ tp->t_rttlow = ticks - tp->t_rtttime;
tcp_xmit_timer(tp,
ticks - tp->t_rtttime);
}
@@ -2077,8 +2083,12 @@ process_ACK:
*/
if ((to.to_flags & TOF_TS) != 0 &&
to.to_tsecr) {
+ if (!tp->t_rttlow || tp->t_rttlow > ticks - to.to_tsecr)
+ tp->t_rttlow = ticks - to.to_tsecr;
tcp_xmit_timer(tp, ticks - to.to_tsecr + 1);
} else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) {
+ if (!tp->t_rttlow || tp->t_rttlow > ticks - tp->t_rtttime)
+ tp->t_rttlow = ticks - tp->t_rtttime;
tcp_xmit_timer(tp, ticks - tp->t_rtttime);
}
tcp_xmit_bandwidth_limit(tp, th->th_ack);
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 9267ea2656cb..e61d54143b23 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -193,6 +193,11 @@ static int tcp_inflight_debug = 0;
SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, debug, CTLFLAG_RW,
&tcp_inflight_debug, 0, "Debug TCP inflight calculations");
+static int tcp_inflight_rttthresh;
+SYSCTL_PROC(_net_inet_tcp_inflight, OID_AUTO, rttthresh, CTLTYPE_INT|CTLFLAG_RW,
+ &tcp_inflight_rttthresh, 0, sysctl_msec_to_ticks, "I",
+ "RTT threshold below which inflight will deactivate itself");
+
static int tcp_inflight_min = 6144;
SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, min, CTLFLAG_RW,
&tcp_inflight_min, 0, "Lower-bound for TCP inflight window");
@@ -253,6 +258,7 @@ tcp_init()
tcp_msl = TCPTV_MSL;
tcp_rexmit_min = TCPTV_MIN;
tcp_rexmit_slop = TCPTV_CPU_VAR;
+ tcp_inflight_rttthresh = TCPTV_INFLIGHT_RTTTHRESH;
INP_INFO_LOCK_INIT(&tcbinfo, "tcp");
LIST_INIT(&tcb);
@@ -1937,7 +1943,7 @@ tcp_xmit_bandwidth_limit(struct tcpcb *tp, tcp_seq ack_seq)
* If inflight_enable is disabled in the middle of a tcp connection,
* make sure snd_bwnd is effectively disabled.
*/
- if (tcp_inflight_enable == 0) {
+ if (tcp_inflight_enable == 0 || tp->t_rttlow < tcp_inflight_rttthresh) {
tp->snd_bwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
tp->snd_bandwidth = 0;
return;
diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h
index c62060fe85cf..d3d7c94ff3b0 100644
--- a/sys/netinet/tcp_timer.h
+++ b/sys/netinet/tcp_timer.h
@@ -86,6 +86,9 @@
#define TCPTV_KEEPINTVL ( 75*hz) /* default probe interval */
#define TCPTV_KEEPCNT 8 /* max probes before drop */
+#define TCPTV_INFLIGHT_RTTTHRESH (10*hz/1000) /* below which inflight
+ disengages, in msec */
+
/*
* Minimum retransmit timer is 3 ticks, for algorithmic stability.
* TCPT_RANGESET() will add another TCPTV_CPU_VAR to deal with
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 9267ea2656cb..e61d54143b23 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -193,6 +193,11 @@ static int tcp_inflight_debug = 0;
SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, debug, CTLFLAG_RW,
&tcp_inflight_debug, 0, "Debug TCP inflight calculations");
+static int tcp_inflight_rttthresh;
+SYSCTL_PROC(_net_inet_tcp_inflight, OID_AUTO, rttthresh, CTLTYPE_INT|CTLFLAG_RW,
+ &tcp_inflight_rttthresh, 0, sysctl_msec_to_ticks, "I",
+ "RTT threshold below which inflight will deactivate itself");
+
static int tcp_inflight_min = 6144;
SYSCTL_INT(_net_inet_tcp_inflight, OID_AUTO, min, CTLFLAG_RW,
&tcp_inflight_min, 0, "Lower-bound for TCP inflight window");
@@ -253,6 +258,7 @@ tcp_init()
tcp_msl = TCPTV_MSL;
tcp_rexmit_min = TCPTV_MIN;
tcp_rexmit_slop = TCPTV_CPU_VAR;
+ tcp_inflight_rttthresh = TCPTV_INFLIGHT_RTTTHRESH;
INP_INFO_LOCK_INIT(&tcbinfo, "tcp");
LIST_INIT(&tcb);
@@ -1937,7 +1943,7 @@ tcp_xmit_bandwidth_limit(struct tcpcb *tp, tcp_seq ack_seq)
* If inflight_enable is disabled in the middle of a tcp connection,
* make sure snd_bwnd is effectively disabled.
*/
- if (tcp_inflight_enable == 0) {
+ if (tcp_inflight_enable == 0 || tp->t_rttlow < tcp_inflight_rttthresh) {
tp->snd_bwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
tp->snd_bandwidth = 0;
return;
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index b1515ddf6d29..f9050df1d8af 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -199,6 +199,7 @@ struct tcpcb {
tcp_seq sack_newdata; /* New data xmitted in this recovery
episode starts at this seq number */
struct sackhint sackhint; /* SACK scoreboard hint */
+ int t_rttlow; /* smallest observerved RTT */
};
#define IN_FASTRECOVERY(tp) (tp->t_flags & TF_FASTRECOVERY)