Message ID | Pine.LNX.4.64.0904021216170.30150@wrl-59.cs.helsinki.fi |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: "Ilpo Järvinen" <ilpo.jarvinen@helsinki.fi> Date: Thu, 2 Apr 2009 12:18:20 +0300 (EEST) > > It seems that trivial reset of pcount to one was not sufficient > in tcp_retransmit_skb. Multiple counters experience a positive > miscount when skb's pcount gets lowered without the necessary > adjustments (depending on skb's sacked bits which exactly), at > worst a packets_out miscount can crash at RTO if the write queue > is empty! > > Triggering this requires mss change, so bidir tcp or mtu probe or > like. > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> > Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de> > Tested-by: Uwe Bugla <uwe.bugla@gmx.de> Applied. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f1db89b..53300fa 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1893,7 +1893,12 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) if (tcp_fragment(sk, skb, cur_mss, cur_mss)) return -ENOMEM; /* We'll try again later. */ } else { - tcp_init_tso_segs(sk, skb, cur_mss); + int oldpcount = tcp_skb_pcount(skb); + + if (unlikely(oldpcount > 1)) { + tcp_init_tso_segs(sk, skb, cur_mss); + tcp_adjust_pcount(sk, skb, oldpcount - tcp_skb_pcount(skb)); + } } tcp_retrans_try_collapse(sk, skb, cur_mss);