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.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index f5622b250665..cc2ac5346b92 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4249,6 +4249,8 @@ static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq)
4249 * If the sack array is full, forget about the last one. 4249 * If the sack array is full, forget about the last one.
4250 */ 4250 */
4251 if (this_sack >= TCP_NUM_SACKS) { 4251 if (this_sack >= TCP_NUM_SACKS) {
4252 if (tp->compressed_ack)
4253 tcp_send_ack(sk);
4252 this_sack--; 4254 this_sack--;
4253 tp->rx_opt.num_sacks--; 4255 tp->rx_opt.num_sacks--;
4254 sp--; 4256 sp--;
@@ -5081,6 +5083,7 @@ static inline void tcp_data_snd_check(struct sock *sk)
5081static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible) 5083static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
5082{ 5084{
5083 struct tcp_sock *tp = tcp_sk(sk); 5085 struct tcp_sock *tp = tcp_sk(sk);
5086 unsigned long rtt, delay;
5084 5087
5085 /* More than one full frame received... */ 5088 /* More than one full frame received... */
5086 if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && 5089 if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss &&
@@ -5092,15 +5095,35 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
5092 (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat || 5095 (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat ||
5093 __tcp_select_window(sk) >= tp->rcv_wnd)) || 5096 __tcp_select_window(sk) >= tp->rcv_wnd)) ||
5094 /* We ACK each frame or... */ 5097 /* We ACK each frame or... */
5095 tcp_in_quickack_mode(sk) || 5098 tcp_in_quickack_mode(sk)) {
5096 /* We have out of order data. */ 5099send_now:
5097 (ofo_possible && !RB_EMPTY_ROOT(&tp->out_of_order_queue))) {
5098 /* Then ack it now */
5099 tcp_send_ack(sk); 5100 tcp_send_ack(sk);
5100 } else { 5101 return;
5101 /* Else, send delayed ack. */ 5102 }
5103
5104 if (!ofo_possible || RB_EMPTY_ROOT(&tp->out_of_order_queue)) {
5102 tcp_send_delayed_ack(sk); 5105 tcp_send_delayed_ack(sk);
5106 return;
5103 } 5107 }
5108
5109 if (!tcp_is_sack(tp) || tp->compressed_ack >= 44)
5110 goto send_now;
5111 tp->compressed_ack++;
5112
5113 if (hrtimer_is_queued(&tp->compressed_ack_timer))
5114 return;
5115
5116 /* compress ack timer : 5 % of rtt, but no more than 1 ms */
5117
5118 rtt = tp->rcv_rtt_est.rtt_us;
5119 if (tp->srtt_us && tp->srtt_us < rtt)
5120 rtt = tp->srtt_us;
5121
5122 delay = min_t(unsigned long, NSEC_PER_MSEC,
5123 rtt * (NSEC_PER_USEC >> 3)/20);
5124 sock_hold(sk);
5125 hrtimer_start(&tp->compressed_ack_timer, ns_to_ktime(delay),
5126 HRTIMER_MODE_REL_PINNED_SOFT);
5104} 5127}
5105 5128
5106static inline void tcp_ack_snd_check(struct sock *sk) 5129static inline void tcp_ack_snd_check(struct sock *sk)