aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_timer.c')
-rw-r--r--net/ipv4/tcp_timer.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index d212f183dd2d..a242f8874629 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -36,6 +36,21 @@ u32 tcp_retransmit_stamp(const struct sock *sk)
36 return start_ts; 36 return start_ts;
37} 37}
38 38
39static u32 tcp_clamp_rto_to_user_timeout(const struct sock *sk)
40{
41 struct inet_connection_sock *icsk = inet_csk(sk);
42 u32 elapsed, start_ts;
43
44 start_ts = tcp_retransmit_stamp(sk);
45 if (!icsk->icsk_user_timeout || !start_ts)
46 return icsk->icsk_rto;
47 elapsed = tcp_time_stamp(tcp_sk(sk)) - start_ts;
48 if (elapsed >= icsk->icsk_user_timeout)
49 return 1; /* user timeout has passed; fire ASAP */
50 else
51 return min_t(u32, icsk->icsk_rto, msecs_to_jiffies(icsk->icsk_user_timeout - elapsed));
52}
53
39/** 54/**
40 * tcp_write_err() - close socket and save error info 55 * tcp_write_err() - close socket and save error info
41 * @sk: The socket the error has appeared on. 56 * @sk: The socket the error has appeared on.
@@ -544,7 +559,8 @@ out_reset_timer:
544 /* Use normal (exponential) backoff */ 559 /* Use normal (exponential) backoff */
545 icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); 560 icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
546 } 561 }
547 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); 562 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
563 tcp_clamp_rto_to_user_timeout(sk), TCP_RTO_MAX);
548 if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0)) 564 if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0))
549 __sk_dst_reset(sk); 565 __sk_dst_reset(sk);
550 566