Re: 2.6.9 failed assertion in tcp_timer.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Oct 23, 2004 at 07:50:40AM +1000, herbert wrote:
>
> So we don't really know whether it went further or not :)

Actually, I think we've caught your crash now.  If that code path
is triggering at all, then it'll trigger with TSO packets too.  If
we get a truly partial ack on a TSO packet, then tcp_tso_acked will
not trim it off.  So we will fall through to this last-ditch trim
call, which doesn't update packets_out.

There are two solutions to this problem.  I've taken the simpler
approach for now.  We simply trim off the partial bits in tcp_tso_acked
and live with the fact that the packet counters may differ from
what's on the netwrok by one.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Later on we can "fix" this by remembering where the original TSO
packet started from, perhaps in skb->h or somewhere.  Dave, is this
worth it?

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
===== net/ipv4/tcp_input.c 1.81 vs edited =====
--- 1.81/net/ipv4/tcp_input.c	2004-10-04 07:31:39 +10:00
+++ edited/net/ipv4/tcp_input.c	2004-10-23 09:12:42 +10:00
@@ -2369,25 +2369,19 @@
 {
 	struct tcp_opt *tp = tcp_sk(sk);
 	struct tcp_skb_cb *scb = TCP_SKB_CB(skb); 
-	__u32 mss = tcp_skb_mss(skb);
-	__u32 snd_una = tp->snd_una;
-	__u32 orig_seq, seq;
-	__u32 packets_acked = 0;
+	__u32 seq = tp->snd_una;
+	__u32 packets_acked;
 	int acked = 0;
 
 	/* If we get here, the whole TSO packet has not been
 	 * acked.
 	 */
-	BUG_ON(!after(scb->end_seq, snd_una));
+	BUG_ON(!after(scb->end_seq, seq));
 
-	seq = orig_seq = scb->seq;
-	while (!after(seq + mss, snd_una)) {
-		packets_acked++;
-		seq += mss;
-	}
-
-	if (tcp_trim_head(sk, skb, (seq - orig_seq)))
+	packets_acked = tcp_skb_pcount(skb);
+	if (tcp_trim_head(sk, skb, seq - scb->seq))
 		return 0;
+	packets_acked -= tcp_skb_pcount(skb);
 
 	if (packets_acked) {
 		__u8 sacked = scb->sacked;
--- linux-2.6/net/ipv4/tcp_output.c.orig	2004-10-23 08:44:16.000000000 +1000
+++ linux-2.6/net/ipv4/tcp_output.c	2004-10-23 09:10:13.000000000 +1000
@@ -588,7 +588,7 @@
 	/* Any change of skb->len requires recalculation of tso
 	 * factor and mss.
 	 */
-	if (tcp_skb_mss(skb))
+	if (tcp_skb_pcount(skb) > 1)
 		tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb));
 
 	return 0;

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux