diff options
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 12 | ||||
-rw-r--r-- | include/linux/tcp.h | 4 | ||||
-rw-r--r-- | include/net/tcp.h | 1 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 7 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 7 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 12 |
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 | ||
502 | tcp_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 | |||
502 | UDP variables: | 514 | UDP variables: |
503 | 515 | ||
504 | udp_mem - vector of 3 INTEGERs: min, pressure, max | 516 | udp_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; | |||
245 | extern int sysctl_tcp_max_ssthresh; | 245 | extern int sysctl_tcp_max_ssthresh; |
246 | extern int sysctl_tcp_cookie_size; | 246 | extern int sysctl_tcp_cookie_size; |
247 | extern int sysctl_tcp_thin_linear_timeouts; | 247 | extern int sysctl_tcp_thin_linear_timeouts; |
248 | extern int sysctl_tcp_thin_dupack; | ||
248 | 249 | ||
249 | extern atomic_t tcp_memory_allocated; | 250 | extern atomic_t tcp_memory_allocated; |
250 | extern struct percpu_counter tcp_sockets_allocated; | 251 | extern 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; | |||
89 | int sysctl_tcp_frto_response __read_mostly; | 89 | int sysctl_tcp_frto_response __read_mostly; |
90 | int sysctl_tcp_nometrics_save __read_mostly; | 90 | int sysctl_tcp_nometrics_save __read_mostly; |
91 | 91 | ||
92 | int sysctl_tcp_thin_dupack __read_mostly; | ||
93 | |||
92 | int sysctl_tcp_moderate_rcvbuf __read_mostly = 1; | 94 | int sysctl_tcp_moderate_rcvbuf __read_mostly = 1; |
93 | int sysctl_tcp_abc __read_mostly; | 95 | int 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 | ||