Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e2fd555 authored by Lennert Buytenhek's avatar Lennert Buytenhek Committed by David S. Miller
Browse files

gianfar: fix BUG under load after introduction of skb recycling



Since commit 0fd56bb5 ("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: default avatarMichael Guntsche <mike@it-loops.com>
Tested-by: default avatarMichael Guntsche <mike@it-loops.com>
Signed-off-by: default avatarLennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0975ecba
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -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++;