diff options
Diffstat (limited to 'net/ipv4/tcp_timer.c')
-rw-r--r-- | net/ipv4/tcp_timer.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 8816a20c2597..b2e6bbccaee1 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -29,6 +29,7 @@ int sysctl_tcp_keepalive_intvl __read_mostly = TCP_KEEPALIVE_INTVL; | |||
29 | int sysctl_tcp_retries1 __read_mostly = TCP_RETR1; | 29 | int sysctl_tcp_retries1 __read_mostly = TCP_RETR1; |
30 | int sysctl_tcp_retries2 __read_mostly = TCP_RETR2; | 30 | int sysctl_tcp_retries2 __read_mostly = TCP_RETR2; |
31 | int sysctl_tcp_orphan_retries __read_mostly; | 31 | int sysctl_tcp_orphan_retries __read_mostly; |
32 | int sysctl_tcp_thin_linear_timeouts __read_mostly; | ||
32 | 33 | ||
33 | static void tcp_write_timer(unsigned long); | 34 | static void tcp_write_timer(unsigned long); |
34 | static void tcp_delack_timer(unsigned long); | 35 | static void tcp_delack_timer(unsigned long); |
@@ -133,7 +134,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) | |||
133 | } | 134 | } |
134 | 135 | ||
135 | /* This function calculates a "timeout" which is equivalent to the timeout of a | 136 | /* This function calculates a "timeout" which is equivalent to the timeout of a |
136 | * TCP connection after "boundary" unsucessful, exponentially backed-off | 137 | * TCP connection after "boundary" unsuccessful, exponentially backed-off |
137 | * retransmissions with an initial RTO of TCP_RTO_MIN. | 138 | * retransmissions with an initial RTO of TCP_RTO_MIN. |
138 | */ | 139 | */ |
139 | static bool retransmits_timed_out(struct sock *sk, | 140 | static bool retransmits_timed_out(struct sock *sk, |
@@ -415,7 +416,25 @@ void tcp_retransmit_timer(struct sock *sk) | |||
415 | icsk->icsk_retransmits++; | 416 | icsk->icsk_retransmits++; |
416 | 417 | ||
417 | out_reset_timer: | 418 | out_reset_timer: |
418 | icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); | 419 | /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is |
420 | * used to reset timer, set to 0. Recalculate 'icsk_rto' as this | ||
421 | * might be increased if the stream oscillates between thin and thick, | ||
422 | * thus the old value might already be too high compared to the value | ||
423 | * set by 'tcp_set_rto' in tcp_input.c which resets the rto without | ||
424 | * backoff. Limit to TCP_THIN_LINEAR_RETRIES before initiating | ||
425 | * exponential backoff behaviour to avoid continue hammering | ||
426 | * linear-timeout retransmissions into a black hole | ||
427 | */ | ||
428 | if (sk->sk_state == TCP_ESTABLISHED && | ||
429 | (tp->thin_lto || sysctl_tcp_thin_linear_timeouts) && | ||
430 | tcp_stream_is_thin(tp) && | ||
431 | icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) { | ||
432 | icsk->icsk_backoff = 0; | ||
433 | icsk->icsk_rto = min(__tcp_set_rto(tp), TCP_RTO_MAX); | ||
434 | } else { | ||
435 | /* Use normal (exponential) backoff */ | ||
436 | icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); | ||
437 | } | ||
419 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); | 438 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); |
420 | if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1)) | 439 | if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1)) |
421 | __sk_dst_reset(sk); | 440 | __sk_dst_reset(sk); |
@@ -474,6 +493,12 @@ static void tcp_synack_timer(struct sock *sk) | |||
474 | TCP_TIMEOUT_INIT, TCP_RTO_MAX); | 493 | TCP_TIMEOUT_INIT, TCP_RTO_MAX); |
475 | } | 494 | } |
476 | 495 | ||
496 | void tcp_syn_ack_timeout(struct sock *sk, struct request_sock *req) | ||
497 | { | ||
498 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEOUTS); | ||
499 | } | ||
500 | EXPORT_SYMBOL(tcp_syn_ack_timeout); | ||
501 | |||
477 | void tcp_set_keepalive(struct sock *sk, int val) | 502 | void tcp_set_keepalive(struct sock *sk, int val) |
478 | { | 503 | { |
479 | if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) | 504 | if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) |