diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 31 |
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; |