summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2010-09-24 13:22:06 +0000
committerDavid S. Miller <davem@davemloft.net>2010-09-27 14:55:57 -0700
commitb3de7559afbb7a8a35b4be975a6adf6c5e3cdca0 (patch)
treeb387ee28cbb0c577943e87ddc7d87c3d7c65b99c
parent3fd6c88ef875a14740801ebfc6b6e4e064a1cdd4 (diff)
downloadlinux-b3de7559afbb7a8a35b4be975a6adf6c5e3cdca0.tar.gz
linux-b3de7559afbb7a8a35b4be975a6adf6c5e3cdca0.tar.bz2
linux-b3de7559afbb7a8a35b4be975a6adf6c5e3cdca0.zip
tcp: fix TSO FACK loss marking in tcp_mark_head_lost
When TCP uses FACK algorithm to mark lost packets in tcp_mark_head_lost(), if the number of packets in the (TSO) skb is greater than the number of packets that should be marked lost, TCP incorrectly exits the loop and marks no packets lost in the skb. This underestimates tp->lost_out and affects the recovery/retransmission. This patch fargments the skb and marks the correct amount of packets lost. Signed-off-by: Yuchung Cheng <ycheng@google.com> Acked-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/tcp_input.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 149e79ac2891..b55f60f6fcbe 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2545,7 +2545,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
cnt += tcp_skb_pcount(skb);
if (cnt > packets) {
- if (tcp_is_sack(tp) || (oldcnt >= packets))
+ if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) ||
+ (oldcnt >= packets))
break;
mss = skb_shinfo(skb)->gso_size;