linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eran Liberty <liberty@extricom.com>
To: David Miller <davem@davemloft.net>
Cc: galak@kernel.crashing.org, LKML <linux-kernel@vger.kernel.org>
Subject: [PATCH] gainfar.c : skb_over_panic (kernel-2.6.32.15)
Date: Tue, 29 Jun 2010 18:42:21 +0300	[thread overview]
Message-ID: <4C2A145D.1000702@extricom.com> (raw)
In-Reply-To: <20100628.113336.112593735.davem@davemloft.net>

[-- Attachment #1: Type: text/plain, Size: 1309 bytes --]

David Miller wrote:
> From: Eran Liberty <liberty@extricom.com>
> Date: Mon, 28 Jun 2010 10:57:08 +0300
>
>   
>> This code has proved to be insufficient and produce
>> skb_over_panic. The proposed patch fix this.
>>     
>
> Then you have to post a patch relative to the current code, rather than
> against the code as it was several releases ago.
>
> Your patch didn't apply, so I can't use it.
>
>   
Upon cleaning up my patch for the latest kernel I realized I do not
like: the previous partial fix, the fix in ucc_geth.c, the fix in the
current latest kernel, and my own previously proposed patch. They all
tried to undo the alignment skb_reserve done in gfar_new_skb() before
queuing the skb into the rw_recycle, because upon getting a new one in
gfar_new_skb() if the skb is from the rx_recycle pool rather then newly
allocated it is reserved twice.

Instead of trying to undo the skb_reserve this proposed patch will make
sure the alignment skb_reserve is done once, upon allocating the skb and
not when taken out of the rx_recycle pool. Eliminating the need to undo
anything before queue skb back to the pool.

This patch will apply cleanly against the 2.6.32.15. Another patch will
be submitted separately for the current Linus tree.

-- Liberty

Signed-off-by: Eran Liberty <liberty@extricom.com>


[-- Attachment #2: gianfar_skb_over_panic.patch --]
[-- Type: text/x-diff, Size: 2484 bytes --]

---
 drivers/net/gianfar.c |   52 +++++++++++++++++++++++++-------------------------
 1 file changed, 27 insertions(+), 25 deletions(-)

--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1568,6 +1568,15 @@
 	schedule_work(&priv->reset_task);
 }
 
+static void gfar_align_skb(struct sk_buff *skb)
+{
+	/* 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, RXBUF_ALIGNMENT -
+		(((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1)));
+}
+
 /* Interrupt Handler for Transmit complete */
 static int gfar_clean_tx_ring(struct net_device *dev)
 {
@@ -1620,9 +1629,10 @@
 		 */
 		if (skb_queue_len(&priv->rx_recycle) < priv->rx_ring_size &&
 				skb_recycle_check(skb, priv->rx_buffer_size +
-					RXBUF_ALIGNMENT))
+					RXBUF_ALIGNMENT)) {
+			gfar_align_skb(skb);
 			__skb_queue_head(&priv->rx_recycle, skb);
-		else
+		} else
 			dev_kfree_skb_any(skb);
 
 		priv->tx_skbuff[skb_dirtytx] = NULL;
@@ -1696,28 +1706,29 @@
 	bdp->lstatus = lstatus;
 }
 
+static struct sk_buff * gfar_alloc_skb(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct sk_buff *skb = NULL;
+
+	skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT);
+	if (!skb)
+		return NULL;
+
+	gfar_align_skb(skb);
+
+	return skb;
+}
 
 struct sk_buff * gfar_new_skb(struct net_device *dev)
 {
-	unsigned int alignamount;
 	struct gfar_private *priv = netdev_priv(dev);
 	struct sk_buff *skb = NULL;
 
 	skb = __skb_dequeue(&priv->rx_recycle);
-	if (!skb)
-		skb = netdev_alloc_skb(dev,
-				priv->rx_buffer_size + RXBUF_ALIGNMENT);
 
 	if (!skb)
-		return NULL;
-
-	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);
+		skb = gfar_alloc_skb(dev);
 
 	return skb;
 }
@@ -1853,17 +1864,8 @@
 
 			if (unlikely(!newskb))
 				newskb = 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;
+			else if (skb)
 				__skb_queue_head(&priv->rx_recycle, skb);
-			}
 		} else {
 			/* Increment the number of packets */
 			dev->stats.rx_packets++;


  reply	other threads:[~2010-06-29 15:40 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-24  9:53 [PATCH] gainfar.c : skb_over_panic (kernel-2.6.32.15) Eran Liberty
2010-06-24 21:52 ` David Miller
2010-06-28  7:57   ` Eran Liberty
2010-06-28 18:33     ` David Miller
2010-06-29 15:42       ` Eran Liberty [this message]
2010-06-29 16:20         ` [PATCH] gainfar.c : code cleanup Eran Liberty
2010-09-29  0:35         ` [PATCH] gainfar.c : skb_over_panic (kernel-2.6.32.15) emin ak
2010-10-03  9:32           ` Eran Liberty
2010-10-03 10:54             ` emin ak
2010-10-03 14:48               ` Eran Liberty

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C2A145D.1000702@extricom.com \
    --to=liberty@extricom.com \
    --cc=davem@davemloft.net \
    --cc=galak@kernel.crashing.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).