[PATCH] tcp: fix TSO cwnd caching bug

tcp_write_xmit caches the cwnd value indirectly in cwnd_quota. When
tcp_transmit_skb reduces the cwnd because of tcp_enter_cwr, the cached
value becomes invalid.

This patch ensures that the cwnd value is always reread after each
tcp_transmit_skb call.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Herbert Xu and committed by Linus Torvalds b68e9f85 846998ae

+9 -25
+9 -25
net/ipv4/tcp_output.c
··· 972 if (unlikely(sk->sk_state == TCP_CLOSE)) 973 return 0; 974 975 - skb = sk->sk_send_head; 976 - if (unlikely(!skb)) 977 - return 0; 978 - 979 - tso_segs = tcp_init_tso_segs(sk, skb, mss_now); 980 - cwnd_quota = tcp_cwnd_test(tp, skb); 981 - if (unlikely(!cwnd_quota)) 982 - goto out; 983 - 984 sent_pkts = 0; 985 - while (likely(tcp_snd_wnd_test(tp, skb, mss_now))) { 986 BUG_ON(!tso_segs); 987 988 if (tso_segs == 1) { 989 if (unlikely(!tcp_nagle_test(tp, skb, mss_now, ··· 1025 1026 tcp_minshall_update(tp, mss_now, skb); 1027 sent_pkts++; 1028 - 1029 - /* Do not optimize this to use tso_segs. If we chopped up 1030 - * the packet above, tso_segs will no longer be valid. 1031 - */ 1032 - cwnd_quota -= tcp_skb_pcount(skb); 1033 - 1034 - BUG_ON(cwnd_quota < 0); 1035 - if (!cwnd_quota) 1036 - break; 1037 - 1038 - skb = sk->sk_send_head; 1039 - if (!skb) 1040 - break; 1041 - tso_segs = tcp_init_tso_segs(sk, skb, mss_now); 1042 } 1043 1044 if (likely(sent_pkts)) { 1045 tcp_cwnd_validate(sk, tp); 1046 return 0; 1047 } 1048 - out: 1049 return !tp->packets_out && sk->sk_send_head; 1050 } 1051
··· 972 if (unlikely(sk->sk_state == TCP_CLOSE)) 973 return 0; 974 975 sent_pkts = 0; 976 + while ((skb = sk->sk_send_head)) { 977 + tso_segs = tcp_init_tso_segs(sk, skb, mss_now); 978 BUG_ON(!tso_segs); 979 + 980 + cwnd_quota = tcp_cwnd_test(tp, skb); 981 + if (!cwnd_quota) 982 + break; 983 + 984 + if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now))) 985 + break; 986 987 if (tso_segs == 1) { 988 if (unlikely(!tcp_nagle_test(tp, skb, mss_now, ··· 1026 1027 tcp_minshall_update(tp, mss_now, skb); 1028 sent_pkts++; 1029 } 1030 1031 if (likely(sent_pkts)) { 1032 tcp_cwnd_validate(sk, tp); 1033 return 0; 1034 } 1035 return !tp->packets_out && sk->sk_send_head; 1036 } 1037