[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20090523115143.GB1672@mail.wantstofly.org>
Date: Sat, 23 May 2009 13:51:43 +0200
From: Lennert Buytenhek <buytenh@...tstofly.org>
To: Andy Fleming <afleming@...escale.com>,
Michael Guntsche <mike@...loops.com>
Cc: davem@...emloft.net, netdev@...r.kernel.org,
linux-kernel@...r.kernel.org, "Rafael J. Wysocki" <rjw@...k.pl>
Subject: [PATCH,RFC] gianfar: fix BUG under load after introduction of skb recycling
Since commit 0fd56bb5be6455d0d42241e65aed057244665e5e ("gianfar:
Add support for skb recycling"), gianfar puts skbuffs that are in
the rx ring back onto the recycle list as-is in case 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.
The RXBUF_ALIGNMENT realignment done in gfar_new_skb() will be done
twice on skbuffs recycled in this way, causing there not to be enough
room in the skb anymore to receive a full packet, eventually leading
to an skb_over_panic from gfar_clean_rx_ring() -> skb_put().
Resetting the skb->data pointer to skb->head + NET_SKB_PAD before
putting the skb back onto the recycle list restores the mentioned
invariant, and should fix this issue.
Reported-by: Michael Guntsche <mike@...loops.com>
Signed-off-by: Lennert Buytenhek <buytenh@...tstofly.org>
---
This might/should/could fix http://bugzilla.kernel.org/show_bug.cgi?id=13293
Michael, can you re-test with this version of the patch?
Andy, can you see if this is OK with you?
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b2c4967..a051918 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1885,8 +1885,17 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
if (unlikely(!newskb))
newskb = skb;
- else if (skb)
+ else if (skb) {
+ /*
+ * We need to reset ->data to what it
+ * was before gfar_new_skb() re-aligned
+ * it to an RXBUF_ALIGNMENT boundary
+ * before we put the skb back on the
+ * recycle list.
+ */
+ skb->data = skb->head + NET_SKB_PAD;
__skb_queue_head(&priv->rx_recycle, skb);
+ }
} else {
/* Increment the number of packets */
dev->stats.rx_packets++;
--
1.5.6.4
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists