diff options
author | Angelo P. Castellani <angelo.castellani+lkml@gmail.com> | 2006-05-16 21:42:11 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-05-16 21:42:11 -0700 |
commit | 8872d8e1c4311dd7e5086975df9c76120a0be83b (patch) | |
tree | 1486697e32c65521785721fe9523f4eaee9a3e90 /net/ipv4 | |
parent | d8fd0a73169e90022dc3ccf3083ca24573b44b5c (diff) | |
download | linux-8872d8e1c4311dd7e5086975df9c76120a0be83b.tar.gz linux-8872d8e1c4311dd7e5086975df9c76120a0be83b.tar.bz2 linux-8872d8e1c4311dd7e5086975df9c76120a0be83b.zip |
[TCP]: reno sacked_out count fix
From: "Angelo P. Castellani" <angelo.castellani+lkml@gmail.com>
Using NewReno, if a sk_buff is timed out and is accounted as lost_out,
it should also be removed from the sacked_out.
This is necessary because recovery using NewReno fast retransmit could
take up to a lot RTTs and the sk_buff RTO can expire without actually
being really lost.
left_out = sacked_out + lost_out
in_flight = packets_out - left_out + retrans_out
Using NewReno without this patch, on very large network losses,
left_out becames bigger than packets_out + retrans_out (!!).
For this reason unsigned integer in_flight overflows to 2^32 - something.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/tcp_input.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9f0cca4c4fae..4a538bc1683d 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1662,6 +1662,8 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_sock *tp) if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; tp->lost_out += tcp_skb_pcount(skb); + if (IsReno(tp)) + tcp_remove_reno_sacks(sk, tp, tcp_skb_pcount(skb) + 1); /* clear xmit_retrans hint */ if (tp->retransmit_skb_hint && |