aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/tcp_input.c16
-rw-r--r--net/ipv4/tcp_timer.c10
2 files changed, 16 insertions, 10 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 1e37c1388189..a9d9555a973f 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -579,10 +579,12 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk,
579 u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr; 579 u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr;
580 u32 delta_us; 580 u32 delta_us;
581 581
582 if (!delta) 582 if (likely(delta < INT_MAX / (USEC_PER_SEC / TCP_TS_HZ))) {
583 delta = 1; 583 if (!delta)
584 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ); 584 delta = 1;
585 tcp_rcv_rtt_update(tp, delta_us, 0); 585 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ);
586 tcp_rcv_rtt_update(tp, delta_us, 0);
587 }
586 } 588 }
587} 589}
588 590
@@ -2910,9 +2912,11 @@ static bool tcp_ack_update_rtt(struct sock *sk, const int flag,
2910 if (seq_rtt_us < 0 && tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr && 2912 if (seq_rtt_us < 0 && tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
2911 flag & FLAG_ACKED) { 2913 flag & FLAG_ACKED) {
2912 u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr; 2914 u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr;
2913 u32 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ);
2914 2915
2915 seq_rtt_us = ca_rtt_us = delta_us; 2916 if (likely(delta < INT_MAX / (USEC_PER_SEC / TCP_TS_HZ))) {
2917 seq_rtt_us = delta * (USEC_PER_SEC / TCP_TS_HZ);
2918 ca_rtt_us = seq_rtt_us;
2919 }
2916 } 2920 }
2917 rs->rtt_us = ca_rtt_us; /* RTT of last (S)ACKed packet (or -1) */ 2921 rs->rtt_us = ca_rtt_us; /* RTT of last (S)ACKed packet (or -1) */
2918 if (seq_rtt_us < 0) 2922 if (seq_rtt_us < 0)
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. */