kfree_skb in tcp_ack (2.0.3x)

Philip Gladstone (philip@raptor.com)
Tue, 30 Sep 1997 10:08:17 -0400


I have a problem with the kfree_skb call in tcp_ack. It turns out
that in my system, I get a number of kfree_skb while still on list.
These turn out to be from the kfree_skb in tcp_ack. It turns
out that after tcp_ack dequeues the skb, it then enables
interrupts, and my driver puts the buffer onto another queue.
Then the tcp_ack code tries to free the buffer.

[You may think that this is an amazing coincidence that the
buffer is removed from the tcp_ack chain just at the time
that it is being transmitted. I suspect that the RTT estimator
is managing to estimate the RTT correctly, and so the ack code
is retransmitting the packet at the same time that the ack is
being received -- hence the collision.]

Question: Why doesn't the tcp_ack code do anything with the
locked bit? Should it really be calling dev_kfree_skb instead?

My feeling is that if the buffer is locked at the time that
tcp_ack wants to dequeue it, then it should not dequeue it, and
it should not free it. Does this seem right?

Philip

p.s. I modified the code from tcp_ack to make it more likely
to fail by adding a 100usec delay between enabling interrupts
and doing the checks.

cli();
if (skb->next)
skb_unlink(skb);
sti();
/*start tmp*/
if (skb->list)
printk(KERN_WARNING "skb (%p) back on list (%p)\n", skb,
skb->list);
udelay(100);
if (skb->list)
printk(KERN_WARNING "delay(100): skb (%p) back on list
(%p)\n", skb, skb->list);
/*end tmp*/
kfree_skb(skb, FREE_WRITE); /* write. */

-- 
Philip Gladstone                           +1 617 487 7700
Raptor Systems, Waltham, MA         http://www.raptor.com/