mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
tcp: fix lost_cnt_hint miscounts
It is possible that lost_cnt_hint gets underflow in tcp_clean_rtx_queue because the cumulative ACK can cover the segment where lost_skb_hint points to only partially, which means that the hint is not cleared, opposite to what my (earlier) comment claimed. Also I don't agree what I ended up writing about non-trivial case there to be what I intented to say. It was not supposed to happen that the hint won't get cleared and we underflow in any scenario. In general, this is quite hard to trigger in practice. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ac11ba753f
commit
59a08cba6a
@ -3273,18 +3273,15 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
|
||||
if (tcp_is_reno(tp)) {
|
||||
tcp_remove_reno_sacks(sk, pkts_acked);
|
||||
} else {
|
||||
int delta;
|
||||
|
||||
/* Non-retransmitted hole got filled? That's reordering */
|
||||
if (reord < prior_fackets)
|
||||
tcp_update_reordering(sk, tp->fackets_out - reord, 0);
|
||||
|
||||
/* No need to care for underflows here because
|
||||
* the lost_skb_hint gets NULLed if we're past it
|
||||
* (or something non-trivial happened)
|
||||
*/
|
||||
if (tcp_is_fack(tp))
|
||||
tp->lost_cnt_hint -= pkts_acked;
|
||||
else
|
||||
tp->lost_cnt_hint -= prior_sacked - tp->sacked_out;
|
||||
delta = tcp_is_fack(tp) ? pkts_acked :
|
||||
prior_sacked - tp->sacked_out;
|
||||
tp->lost_cnt_hint -= min(tp->lost_cnt_hint, delta);
|
||||
}
|
||||
|
||||
tp->fackets_out -= min(pkts_acked, tp->fackets_out);
|
||||
|
Loading…
Reference in New Issue
Block a user