From: Greg Kroah-Hartman Date: Thu, 23 Apr 2009 02:35:26 +0000 (-0700) Subject: delete queue-2.6.28/tcp-fix-various-bugs-wrt.-packet-counting-during-fragmentation... X-Git-Tag: v2.6.29.2~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6df0ad4b95ec0b4c42ecea9e3322eec17fcffb8c;p=thirdparty%2Fkernel%2Fstable-queue.git delete queue-2.6.28/tcp-fix-various-bugs-wrt.-packet-counting-during-fragmentation.patch --- diff --git a/queue-2.6.28/series b/queue-2.6.28/series index f9715e87691..92513c380aa 100644 --- a/queue-2.6.28/series +++ b/queue-2.6.28/series @@ -6,7 +6,6 @@ netfilter-nf_conntrack_tcp-fix-unaligned-memory-access-in-tcp_sack.patch xfrm-spin_lock-should-be-spin_unlock-in-xfrm_state.c.patch bridge-bad-error-handling-when-adding-invalid-ether-address.patch bas_gigaset-correctly-allocate-usb-interrupt-transfer-buffer.patch -tcp-fix-various-bugs-wrt.-packet-counting-during-fragmentation.patch 0008-USB-EHCI-add-software-retry-for-transaction-errors.patch 0009-USB-fix-USB_STORAGE_CYPRESS_ATACB.patch 0010-USB-usb-storage-increase-max_sectors-for-tape-driv.patch diff --git a/queue-2.6.28/tcp-fix-various-bugs-wrt.-packet-counting-during-fragmentation.patch b/queue-2.6.28/tcp-fix-various-bugs-wrt.-packet-counting-during-fragmentation.patch deleted file mode 100644 index 8be9fc74bac..00000000000 --- a/queue-2.6.28/tcp-fix-various-bugs-wrt.-packet-counting-during-fragmentation.patch +++ /dev/null @@ -1,203 +0,0 @@ -From e42e8ccda949937872452f571638200f515090c2 Mon Sep 17 00:00:00 2001 -From: Ilpo Järvinen -Date: Sat, 4 Apr 2009 18:12:41 -0700 -Subject: tcp: Fix various bugs wrt. packet counting during fragmentation. - - -[ Upstream commits: d3d2ae454501a4dec360995649e1b002a2ad90c5, - 02276f3c962fd408fa9d441251067845f948bfcf, - 797108d134a91afca9fa59c572336b279bc66afb, - 9eb9362e569062e2f841b7a023e5fcde10ed63b4 ] - --------------------- -tcp: Don't clear hints when tcp_fragmenting - -1) We didn't remove any skbs, so no need to handle stale refs. - -2) scoreboard_skb_hint is trivial, no timestamps were changed - so no need to clear that one - -3) lost_skb_hint needs tweaking similar to that of - tcp_sacktag_one(). - -Signed-off-by: Ilpo Järvinen -Signed-off-by: David S. Miller --------------------- -tcp: fix corner case issue in segmentation during rexmitting - -If cur_mss grew very recently so that the previously G/TSOed skb -now fits well into a single segment it would get send up in -parts unless we calculate # of segments again. This corner-case -could happen eg. after mtu probe completes or less than -previously sack blocks are required for the opposite direction. - -Signed-off-by: Ilpo Järvinen -Signed-off-by: David S. Miller --------------------- -tcp: add helper for counter tweaking due mid-wq change - -We need full-scale adjustment to fix a TCP miscount in the next -patch, so just move it into a helper and call for that from the -other places. - -Signed-off-by: Ilpo Järvinen -Signed-off-by: David S. Miller --------------------- -tcp: miscounts due to tcp_fragment pcount reset - -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 -Reported-by: Markus Trippelsdorf -Tested-by: Uwe Bugla -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman - ---- - include/net/tcp.h | 15 ----------- - net/ipv4/tcp_output.c | 68 ++++++++++++++++++++++++++++++-------------------- - 2 files changed, 41 insertions(+), 42 deletions(-) - ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -610,21 +610,6 @@ static inline int tcp_skb_mss(const stru - return skb_shinfo(skb)->gso_size; - } - --static inline void tcp_dec_pcount_approx_int(__u32 *count, const int decr) --{ -- if (*count) { -- *count -= decr; -- if ((int)*count < 0) -- *count = 0; -- } --} -- --static inline void tcp_dec_pcount_approx(__u32 *count, -- const struct sk_buff *skb) --{ -- tcp_dec_pcount_approx_int(count, tcp_skb_pcount(skb)); --} -- - /* Events passed to congestion control interface */ - enum tcp_ca_event { - CA_EVENT_TX_START, /* first transmit when no packets in flight */ ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -751,6 +751,36 @@ static void tcp_adjust_fackets_out(struc - tp->fackets_out -= decr; - } - -+/* Pcount in the middle of the write queue got changed, we need to do various -+ * tweaks to fix counters -+ */ -+static void tcp_adjust_pcount(struct sock *sk, struct sk_buff *skb, int decr) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tp->packets_out -= decr; -+ -+ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) -+ tp->sacked_out -= decr; -+ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) -+ tp->retrans_out -= decr; -+ if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) -+ tp->lost_out -= decr; -+ -+ /* Reno case is special. Sigh... */ -+ if (tcp_is_reno(tp) && decr > 0) -+ tp->sacked_out -= min_t(u32, tp->sacked_out, decr); -+ -+ tcp_adjust_fackets_out(sk, skb, decr); -+ -+ if (tp->lost_skb_hint && -+ before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(tp->lost_skb_hint)->seq) && -+ (tcp_is_fack(tp) || TCP_SKB_CB(skb)->sacked)) -+ tp->lost_cnt_hint -= decr; -+ -+ tcp_verify_left_out(tp); -+} -+ - /* Function to create two new TCP segments. Shrinks the given segment - * to the specified size and appends a new segment with the rest of the - * packet to the list. This won't be called frequently, I hope. -@@ -767,7 +797,6 @@ int tcp_fragment(struct sock *sk, struct - - BUG_ON(len > skb->len); - -- tcp_clear_retrans_hints_partial(tp); - nsize = skb_headlen(skb) - len; - if (nsize < 0) - nsize = 0; -@@ -834,22 +863,8 @@ int tcp_fragment(struct sock *sk, struct - int diff = old_factor - tcp_skb_pcount(skb) - - tcp_skb_pcount(buff); - -- tp->packets_out -= diff; -- -- if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) -- tp->sacked_out -= diff; -- if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) -- tp->retrans_out -= diff; -- -- if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) -- tp->lost_out -= diff; -- -- /* Adjust Reno SACK estimate. */ -- if (tcp_is_reno(tp) && diff > 0) { -- tcp_dec_pcount_approx_int(&tp->sacked_out, diff); -- tcp_verify_left_out(tp); -- } -- tcp_adjust_fackets_out(sk, skb, diff); -+ if (diff) -+ tcp_adjust_pcount(sk, skb, diff); - } - - /* Link BUFF into the send queue. */ -@@ -1829,22 +1844,14 @@ static void tcp_retrans_try_collapse(str - * packet counting does not break. - */ - TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked & TCPCB_EVER_RETRANS; -- if (TCP_SKB_CB(next_skb)->sacked & TCPCB_SACKED_RETRANS) -- tp->retrans_out -= tcp_skb_pcount(next_skb); -- if (TCP_SKB_CB(next_skb)->sacked & TCPCB_LOST) -- tp->lost_out -= tcp_skb_pcount(next_skb); -- /* Reno case is special. Sigh... */ -- if (tcp_is_reno(tp) && tp->sacked_out) -- tcp_dec_pcount_approx(&tp->sacked_out, next_skb); -- -- tcp_adjust_fackets_out(sk, next_skb, tcp_skb_pcount(next_skb)); -- tp->packets_out -= tcp_skb_pcount(next_skb); - - /* changed transmit queue under us so clear hints */ - tcp_clear_retrans_hints_partial(tp); - if (next_skb == tp->retransmit_skb_hint) - tp->retransmit_skb_hint = skb; - -+ tcp_adjust_pcount(sk, next_skb, tcp_skb_pcount(next_skb)); -+ - sk_wmem_free_skb(sk, next_skb); - } - -@@ -1945,6 +1952,13 @@ int tcp_retransmit_skb(struct sock *sk, - if (skb->len > cur_mss) { - if (tcp_fragment(sk, skb, cur_mss, cur_mss)) - return -ENOMEM; /* We'll try again later. */ -+ } else { -+ 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)); -+ } - } - - /* Collapse two adjacent packets if worthwhile and we can. */