aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Petlund <apetlund@simula.no>2010-02-17 23:48:19 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-18 18:43:09 -0500
commit7e38017557bc0b87434d184f8804cadb102bb903 (patch)
tree30c4a0793bd28f6731ade58786c06f9cf33115df
parent36e31b0af58728071e8023cf8e20c5166b700717 (diff)
net: TCP thin dupack
This patch enables fast retransmissions after one dupACK for TCP if the stream is identified as thin. This will reduce latencies for thin streams that are not able to trigger fast retransmissions due to high packet interarrival time. This mechanism is only active if enabled by iocontrol or syscontrol and the stream is identified as thin. Signed-off-by: Andreas Petlund <apetlund@simula.no> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/ip-sysctl.txt12
-rw-r--r--include/linux/tcp.h4
-rw-r--r--include/net/tcp.h1
-rw-r--r--net/ipv4/sysctl_net_ipv4.c7
-rw-r--r--net/ipv4/tcp.c7
-rw-r--r--net/ipv4/tcp_input.c12
6 files changed, 42 insertions, 1 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index f147310d9af4..2571a62d923e 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -499,6 +499,18 @@ tcp_thin_linear_timeouts - BOOLEAN
499 Documentation/networking/tcp-thin.txt 499 Documentation/networking/tcp-thin.txt
500 Default: 0 500 Default: 0
501 501
502tcp_thin_dupack - BOOLEAN
503 Enable dynamic triggering of retransmissions after one dupACK
504 for thin streams. If set, a check is performed upon reception
505 of a dupACK to determine if the stream is thin (less than 4
506 packets in flight). As long as the stream is found to be thin,
507 data is retransmitted on the first received dupACK. This
508 improves retransmission latency for non-aggressive thin
509 streams, often found to be time-dependent.
510 For more information on thin streams, see
511 Documentation/networking/tcp-thin.txt
512 Default: 0
513
502UDP variables: 514UDP variables:
503 515
504udp_mem - vector of 3 INTEGERs: min, pressure, max 516udp_mem - vector of 3 INTEGERs: min, pressure, max
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 3ba8b074612f..a778ee024590 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -104,6 +104,7 @@ enum {
104#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ 104#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */
105#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */ 105#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */
106#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/ 106#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/
107#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */
107 108
108/* for TCP_INFO socket option */ 109/* for TCP_INFO socket option */
109#define TCPI_OPT_TIMESTAMPS 1 110#define TCPI_OPT_TIMESTAMPS 1
@@ -343,7 +344,8 @@ struct tcp_sock {
343 u8 frto_counter; /* Number of new acks after RTO */ 344 u8 frto_counter; /* Number of new acks after RTO */
344 u8 nonagle : 4,/* Disable Nagle algorithm? */ 345 u8 nonagle : 4,/* Disable Nagle algorithm? */
345 thin_lto : 1,/* Use linear timeouts for thin streams */ 346 thin_lto : 1,/* Use linear timeouts for thin streams */
346 unused : 3; 347 thin_dupack : 1,/* Fast retransmit on first dupack */
348 unused : 2;
347 349
348/* RTT measurement */ 350/* RTT measurement */
349 u32 srtt; /* smoothed round trip time << 3 */ 351 u32 srtt; /* smoothed round trip time << 3 */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 6278fc734abd..56f0aec40ed6 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -245,6 +245,7 @@ extern int sysctl_tcp_slow_start_after_idle;
245extern int sysctl_tcp_max_ssthresh; 245extern int sysctl_tcp_max_ssthresh;
246extern int sysctl_tcp_cookie_size; 246extern int sysctl_tcp_cookie_size;
247extern int sysctl_tcp_thin_linear_timeouts; 247extern int sysctl_tcp_thin_linear_timeouts;
248extern int sysctl_tcp_thin_dupack;
248 249
249extern atomic_t tcp_memory_allocated; 250extern atomic_t tcp_memory_allocated;
250extern struct percpu_counter tcp_sockets_allocated; 251extern struct percpu_counter tcp_sockets_allocated;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index e6a2460587d4..c1bc074f61b7 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -582,6 +582,13 @@ static struct ctl_table ipv4_table[] = {
582 .mode = 0644, 582 .mode = 0644,
583 .proc_handler = proc_dointvec 583 .proc_handler = proc_dointvec
584 }, 584 },
585 {
586 .procname = "tcp_thin_dupack",
587 .data = &sysctl_tcp_thin_dupack,
588 .maxlen = sizeof(int),
589 .mode = 0644,
590 .proc_handler = proc_dointvec
591 },
585 { 592 {
586 .procname = "udp_mem", 593 .procname = "udp_mem",
587 .data = &sysctl_udp_mem, 594 .data = &sysctl_udp_mem,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 21bae9afefea..5901010fad55 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2236,6 +2236,13 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
2236 tp->thin_lto = val; 2236 tp->thin_lto = val;
2237 break; 2237 break;
2238 2238
2239 case TCP_THIN_DUPACK:
2240 if (val < 0 || val > 1)
2241 err = -EINVAL;
2242 else
2243 tp->thin_dupack = val;
2244 break;
2245
2239 case TCP_CORK: 2246 case TCP_CORK:
2240 /* When set indicates to always queue non-full frames. 2247 /* When set indicates to always queue non-full frames.
2241 * Later the user clears this option and we transmit 2248 * Later the user clears this option and we transmit
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3fddc69ccccc..788851ca8c5d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -89,6 +89,8 @@ int sysctl_tcp_frto __read_mostly = 2;
89int sysctl_tcp_frto_response __read_mostly; 89int sysctl_tcp_frto_response __read_mostly;
90int sysctl_tcp_nometrics_save __read_mostly; 90int sysctl_tcp_nometrics_save __read_mostly;
91 91
92int sysctl_tcp_thin_dupack __read_mostly;
93
92int sysctl_tcp_moderate_rcvbuf __read_mostly = 1; 94int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
93int sysctl_tcp_abc __read_mostly; 95int sysctl_tcp_abc __read_mostly;
94 96
@@ -2447,6 +2449,16 @@ static int tcp_time_to_recover(struct sock *sk)
2447 return 1; 2449 return 1;
2448 } 2450 }
2449 2451
2452 /* If a thin stream is detected, retransmit after first
2453 * received dupack. Employ only if SACK is supported in order
2454 * to avoid possible corner-case series of spurious retransmissions
2455 * Use only if there are no unsent data.
2456 */
2457 if ((tp->thin_dupack || sysctl_tcp_thin_dupack) &&
2458 tcp_stream_is_thin(tp) && tcp_dupack_heuristics(tp) > 1 &&
2459 tcp_is_sack(tp) && !tcp_send_head(sk))
2460 return 1;
2461
2450 return 0; 2462 return 0;
2451} 2463}
2452 2464