aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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