aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2868ef28ce52..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)
@@ -4268,7 +4272,7 @@ static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq)
4268 * If the sack array is full, forget about the last one. 4272 * If the sack array is full, forget about the last one.
4269 */ 4273 */
4270 if (this_sack >= TCP_NUM_SACKS) { 4274 if (this_sack >= TCP_NUM_SACKS) {
4271 if (tp->compressed_ack) 4275 if (tp->compressed_ack > TCP_FASTRETRANS_THRESH)
4272 tcp_send_ack(sk); 4276 tcp_send_ack(sk);
4273 this_sack--; 4277 this_sack--;
4274 tp->rx_opt.num_sacks--; 4278 tp->rx_opt.num_sacks--;
@@ -4363,6 +4367,7 @@ static bool tcp_try_coalesce(struct sock *sk,
4363 if (TCP_SKB_CB(from)->has_rxtstamp) { 4367 if (TCP_SKB_CB(from)->has_rxtstamp) {
4364 TCP_SKB_CB(to)->has_rxtstamp = true; 4368 TCP_SKB_CB(to)->has_rxtstamp = true;
4365 to->tstamp = from->tstamp; 4369 to->tstamp = from->tstamp;
4370 skb_hwtstamps(to)->hwtstamp = skb_hwtstamps(from)->hwtstamp;
4366 } 4371 }
4367 4372
4368 return true; 4373 return true;
@@ -5188,7 +5193,17 @@ send_now:
5188 if (!tcp_is_sack(tp) || 5193 if (!tcp_is_sack(tp) ||
5189 tp->compressed_ack >= sock_net(sk)->ipv4.sysctl_tcp_comp_sack_nr) 5194 tp->compressed_ack >= sock_net(sk)->ipv4.sysctl_tcp_comp_sack_nr)
5190 goto send_now; 5195 goto send_now;
5191 tp->compressed_ack++; 5196
5197 if (tp->compressed_ack_rcv_nxt != tp->rcv_nxt) {
5198 tp->compressed_ack_rcv_nxt = tp->rcv_nxt;
5199 if (tp->compressed_ack > TCP_FASTRETRANS_THRESH)
5200 NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPACKCOMPRESSED,
5201 tp->compressed_ack - TCP_FASTRETRANS_THRESH);
5202 tp->compressed_ack = 0;
5203 }
5204
5205 if (++tp->compressed_ack <= TCP_FASTRETRANS_THRESH)
5206 goto send_now;
5192 5207
5193 if (hrtimer_is_queued(&tp->compressed_ack_timer)) 5208 if (hrtimer_is_queued(&tp->compressed_ack_timer))
5194 return; 5209 return;