Patchwork be2net: fix a race in be_xmit()

login
register
mail settings
Submitter Eric Dumazet
Date June 8, 2012, 8:59 a.m.
Message ID <1339145999.6001.62.camel@edumazet-glaptop>
Download mbox | patch
Permalink /patch/163736/
State Accepted
Delegated to: David Miller
Headers show

Comments

Eric Dumazet - June 8, 2012, 8:59 a.m.
From: Eric Dumazet <edumazet@google.com>

As soon as hardware is notified of a transmit, we no longer can assume
skb can be dereferenced, as TX completion might have freed the packet.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Sathya Perla <sathya.perla@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_main.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)



--
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
David Miller - June 8, 2012, 9:44 p.m.
From: <Sathya.Perla@Emulex.Com>
Date: Fri, 8 Jun 2012 03:06:14 -0700

> 
>>-----Original Message-----
>>From: Eric Dumazet <edumazet@google.com>
>>
>>As soon as hardware is notified of a transmit, we no longer can assume
>>skb can be dereferenced, as TX completion might have freed the packet.
>>
>>Signed-off-by: Eric Dumazet <edumazet@google.com>
>>Cc: Sathya Perla <sathya.perla@emulex.com>
> 
> Good catch. Thanks!
> Acked-by: Sathya Perla <sathya.perla@emulex.com>

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

Patch

diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 08efd30..fdb50ce 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -736,6 +736,8 @@  static netdev_tx_t be_xmit(struct sk_buff *skb,
 
 	copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb);
 	if (copied) {
+		int gso_segs = skb_shinfo(skb)->gso_segs;
+
 		/* record the sent skb in the sent_skb table */
 		BUG_ON(txo->sent_skb_list[start]);
 		txo->sent_skb_list[start] = skb;
@@ -753,8 +755,7 @@  static netdev_tx_t be_xmit(struct sk_buff *skb,
 
 		be_txq_notify(adapter, txq->id, wrb_cnt);
 
-		be_tx_stats_update(txo, wrb_cnt, copied,
-				skb_shinfo(skb)->gso_segs, stopped);
+		be_tx_stats_update(txo, wrb_cnt, copied, gso_segs, stopped);
 	} else {
 		txq->head = start;
 		dev_kfree_skb_any(skb);