aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_timer.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2018-11-24 12:12:24 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-24 20:41:37 -0500
commit9efdda4e3abed13f0903b7b6e4d4c2102019440a (patch)
treea65b654f1c7453e5554619e9501670319c8085c8 /net/ipv4/tcp_timer.c
parentd146194f31c96f9b260c5a1cf1592d2e7f82a2e2 (diff)
tcp: address problems caused by EDT misshaps
When a qdisc setup including pacing FQ is dismantled and recreated, some TCP packets are sent earlier than instructed by TCP stack. TCP can be fooled when ACK comes back, because the following operation can return a negative value. tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr; Some paths in TCP stack were not dealing properly with this, this patch addresses four of them. Fixes: ab408b6dc744 ("tcp: switch tcp and sch_fq to new earliest departure time model") Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_timer.c')
-rw-r--r--net/ipv4/tcp_timer.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 5f8b6d3cd855..091c53925e4d 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -40,15 +40,17 @@ static u32 tcp_clamp_rto_to_user_timeout(const struct sock *sk)
40{ 40{
41 struct inet_connection_sock *icsk = inet_csk(sk); 41 struct inet_connection_sock *icsk = inet_csk(sk);
42 u32 elapsed, start_ts; 42 u32 elapsed, start_ts;
43 s32 remaining;
43 44
44 start_ts = tcp_retransmit_stamp(sk); 45 start_ts = tcp_retransmit_stamp(sk);
45 if (!icsk->icsk_user_timeout || !start_ts) 46 if (!icsk->icsk_user_timeout || !start_ts)
46 return icsk->icsk_rto; 47 return icsk->icsk_rto;
47 elapsed = tcp_time_stamp(tcp_sk(sk)) - start_ts; 48 elapsed = tcp_time_stamp(tcp_sk(sk)) - start_ts;
48 if (elapsed >= icsk->icsk_user_timeout) 49 remaining = icsk->icsk_user_timeout - elapsed;
50 if (remaining <= 0)
49 return 1; /* user timeout has passed; fire ASAP */ 51 return 1; /* user timeout has passed; fire ASAP */
50 else 52
51 return min_t(u32, icsk->icsk_rto, msecs_to_jiffies(icsk->icsk_user_timeout - elapsed)); 53 return min_t(u32, icsk->icsk_rto, msecs_to_jiffies(remaining));
52} 54}
53 55
54/** 56/**
@@ -209,7 +211,7 @@ static bool retransmits_timed_out(struct sock *sk,
209 (boundary - linear_backoff_thresh) * TCP_RTO_MAX; 211 (boundary - linear_backoff_thresh) * TCP_RTO_MAX;
210 timeout = jiffies_to_msecs(timeout); 212 timeout = jiffies_to_msecs(timeout);
211 } 213 }
212 return (tcp_time_stamp(tcp_sk(sk)) - start_ts) >= timeout; 214 return (s32)(tcp_time_stamp(tcp_sk(sk)) - start_ts - timeout) >= 0;
213} 215}
214 216
215/* A write timeout has occurred. Process the after effects. */ 217/* A write timeout has occurred. Process the after effects. */