summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2009-02-28 04:44:28 +0000
committerDavid S. Miller <davem@davemloft.net>2009-03-02 03:00:09 -0800
commit59a08cba6a604a265e45e9b970e372554cf46627 (patch)
tree044bc6b23d3bd6a786dafb763363fa1da89afa65
parentac11ba753f3aa839292c1a3b6c971c637ad2e839 (diff)
downloadop-kernel-dev-59a08cba6a604a265e45e9b970e372554cf46627.zip
op-kernel-dev-59a08cba6a604a265e45e9b970e372554cf46627.tar.gz
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>
-rw-r--r--net/ipv4/tcp_input.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c28976a7..3f2f090 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -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);
OpenPOWER on IntegriCloud