diff options
Diffstat (limited to 'net/ipv4/tcp_recovery.c')
-rw-r--r-- | net/ipv4/tcp_recovery.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c index d3ea89020c69..3a81720ac0c4 100644 --- a/net/ipv4/tcp_recovery.c +++ b/net/ipv4/tcp_recovery.c | |||
@@ -55,7 +55,8 @@ static void tcp_rack_detect_loss(struct sock *sk, u32 *reo_timeout) | |||
55 | * to queuing or delayed ACKs. | 55 | * to queuing or delayed ACKs. |
56 | */ | 56 | */ |
57 | reo_wnd = 1000; | 57 | reo_wnd = 1000; |
58 | if ((tp->rack.reord || !tp->lost_out) && min_rtt != ~0U) { | 58 | if ((tp->rack.reord || inet_csk(sk)->icsk_ca_state < TCP_CA_Recovery) && |
59 | min_rtt != ~0U) { | ||
59 | reo_wnd = max((min_rtt >> 2) * tp->rack.reo_wnd_steps, reo_wnd); | 60 | reo_wnd = max((min_rtt >> 2) * tp->rack.reo_wnd_steps, reo_wnd); |
60 | reo_wnd = min(reo_wnd, tp->srtt_us >> 3); | 61 | reo_wnd = min(reo_wnd, tp->srtt_us >> 3); |
61 | } | 62 | } |
@@ -79,12 +80,12 @@ static void tcp_rack_detect_loss(struct sock *sk, u32 *reo_timeout) | |||
79 | */ | 80 | */ |
80 | remaining = tp->rack.rtt_us + reo_wnd - | 81 | remaining = tp->rack.rtt_us + reo_wnd - |
81 | tcp_stamp_us_delta(tp->tcp_mstamp, skb->skb_mstamp); | 82 | tcp_stamp_us_delta(tp->tcp_mstamp, skb->skb_mstamp); |
82 | if (remaining < 0) { | 83 | if (remaining <= 0) { |
83 | tcp_rack_mark_skb_lost(sk, skb); | 84 | tcp_rack_mark_skb_lost(sk, skb); |
84 | list_del_init(&skb->tcp_tsorted_anchor); | 85 | list_del_init(&skb->tcp_tsorted_anchor); |
85 | } else { | 86 | } else { |
86 | /* Record maximum wait time (+1 to avoid 0) */ | 87 | /* Record maximum wait time */ |
87 | *reo_timeout = max_t(u32, *reo_timeout, 1 + remaining); | 88 | *reo_timeout = max_t(u32, *reo_timeout, remaining); |
88 | } | 89 | } |
89 | } | 90 | } |
90 | } | 91 | } |
@@ -116,13 +117,8 @@ void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq, | |||
116 | { | 117 | { |
117 | u32 rtt_us; | 118 | u32 rtt_us; |
118 | 119 | ||
119 | if (tp->rack.mstamp && | ||
120 | !tcp_rack_sent_after(xmit_time, tp->rack.mstamp, | ||
121 | end_seq, tp->rack.end_seq)) | ||
122 | return; | ||
123 | |||
124 | rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, xmit_time); | 120 | rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, xmit_time); |
125 | if (sacked & TCPCB_RETRANS) { | 121 | if (rtt_us < tcp_min_rtt(tp) && (sacked & TCPCB_RETRANS)) { |
126 | /* If the sacked packet was retransmitted, it's ambiguous | 122 | /* If the sacked packet was retransmitted, it's ambiguous |
127 | * whether the retransmission or the original (or the prior | 123 | * whether the retransmission or the original (or the prior |
128 | * retransmission) was sacked. | 124 | * retransmission) was sacked. |
@@ -133,13 +129,15 @@ void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq, | |||
133 | * so it's at least one RTT (i.e., retransmission is at least | 129 | * so it's at least one RTT (i.e., retransmission is at least |
134 | * an RTT later). | 130 | * an RTT later). |
135 | */ | 131 | */ |
136 | if (rtt_us < tcp_min_rtt(tp)) | 132 | return; |
137 | return; | ||
138 | } | 133 | } |
139 | tp->rack.rtt_us = rtt_us; | ||
140 | tp->rack.mstamp = xmit_time; | ||
141 | tp->rack.end_seq = end_seq; | ||
142 | tp->rack.advanced = 1; | 134 | tp->rack.advanced = 1; |
135 | tp->rack.rtt_us = rtt_us; | ||
136 | if (tcp_rack_sent_after(xmit_time, tp->rack.mstamp, | ||
137 | end_seq, tp->rack.end_seq)) { | ||
138 | tp->rack.mstamp = xmit_time; | ||
139 | tp->rack.end_seq = end_seq; | ||
140 | } | ||
143 | } | 141 | } |
144 | 142 | ||
145 | /* We have waited long enough to accommodate reordering. Mark the expired | 143 | /* We have waited long enough to accommodate reordering. Mark the expired |