diff mbox

[BUG] 2.6.30-rc4: Kernel BUG under network load with gianfar

Message ID 9E304569-5828-403D-B4B0-845D8F0D6B95@it-loops.com
State Superseded, archived
Delegated to: David Miller
Headers show

Commit Message

Michael Guntsche May 22, 2009, 2:27 p.m. UTC
On May 22, 2009, at 0:24, David Miller wrote:

> From: Lennert Buytenhek <buytenh@wantstofly.org>
> Date: Wed, 20 May 2009 23:47:34 +0200
>
>> gianfar puts skbuffs that are in the rx ring back onto the recycle
>> list if there was a receive error, but this breaks the following
>> invariant: that all skbuffs on the recycle list have skb->data =
>> skb->head + NET_SKB_PAD (NET_SKB_PAD being 32 for you).
>>
>> In this case, the skb's ->data will be skb->head + RXBUF_ALIGNMENT
>> (where RXBUF_ALIGNMENT is 64) when it is put onto the recycle list.
>> And when gfar_new_skb() picks this skb off the recycle list again,
>> it'll do:
>>
>>        alignamount = RXBUF_ALIGNMENT -
>>                (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1));
>>
>>        /* We need the data buffer to be aligned properly.  We will  
>> reserve
>>         * as many bytes as needed to align the data properly
>>         */
>>        skb_reserve(skb, alignamount);
>>
>> So now skb->data will be skb->head + 128, and there won't be enough
>> space between skb->head and skb->end to hold a full-sized packet.
>>
>> Something like the patch below would fix it.
>
> Let me know when a final, tested, version of this patch is available
> and please make sure it makes it to netdev@vger.kernel.org

I can confirm that Lennert's patch fixes my panic problems here. After  
applying it, my connection has been rock solid and I no longer get any  
kernel panics.
That said, I think the final descision if this patch should go in like  
it is now has to be made by Andy Fleming since he wrote the initial  
code.

Kind regards,
Michael

			dev->stats.rx_packets++;

--
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

Comments

Andy Fleming May 22, 2009, 5:18 p.m. UTC | #1
On May 22, 2009, at 9:27 AM, Michael Guntsche wrote:

>>>
>>> Something like the patch below would fix it.
>>
>> Let me know when a final, tested, version of this patch is available
>> and please make sure it makes it to netdev@vger.kernel.org
>
> I can confirm that Lennert's patch fixes my panic problems here.  
> After applying it, my connection has been rock solid and I no longer  
> get any kernel panics.
> That said, I think the final descision if this patch should go in  
> like it is now has to be made by Andy Fleming since he wrote the  
> initial code.

I'm working (admittedly fairly slowly) on a patch that resets the  
pointers so they don't get moved twice.  That way we can continue to  
benefit from recycling the error skbs.
--
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
Michael Guntsche May 22, 2009, 5:59 p.m. UTC | #2
On May 22, 2009, at 19:18, Andy Fleming wrote:

> I'm working (admittedly fairly slowly) on a patch that resets the  
> pointers so they don't get moved twice.  That way we can continue to  
> benefit from recycling the error skbs.

Ok, thanks for the information. Just tell me when you have a patch  
ready for testing, since it's fairly easy for me to reproduce this  
here with my setup. I'll keep Lennard's patch in the meantime.

Kind regards,
Michael
--
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 mbox

Patch

diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b2c4967..85883c7 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1886,7 +1886,7 @@  int gfar_clean_rx_ring(struct net_device *dev,  
int rx_work_limit)
			if (unlikely(!newskb))
				newskb = skb;
			else if (skb)
-				__skb_queue_head(&priv->rx_recycle, skb);
+				dev_kfree_skb_any(skb);
		} else {
			/* Increment the number of packets */