xen-netfront: Avoid deref'ing skbafter it is potentially freed.
Subsystems (3)
PATCH 1/1 xen-netfront: Avoid deref'ing skbafter it is potentially freed.
xennet_tx_bug_gc can free the skb before we use it, so make sure we don't.
Jeff, this is -rc material.
drivers/net/xen-netfront.c +4 -3
@@ -566,15 +566,16 @@ static int xennet_start_xmit(struct sk_bif (notify)notify_remote_via_irq (np->netdev->irq); + np->stats.tx_bytes += skb->len; + np->stats.tx_packets++; + +/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ xennet_tx_buf_gc (dev);if (!netfront_tx_slot_available (np))netif_stop_queue (dev);spin_unlock_irq (&np->tx_lock); - - np->stats.tx_bytes += skb->len; - np->stats.tx_packets++;return 0 ;
Quoted 21 lines · On Monday 13 August 2007 21:54:37 Jeremy Fitzhardinge wrote:
xennet_tx_bug_gccan free the skb before we use it, so make sure we don't.Jeff, this is -rc material.
Signed-off-by Keir Fraser <[email protected]>Signed-off-by Jeremy Fitzhardinge <[email protected]>Cc Jeff Garzik <[email protected]>diff -r
8bfc43f6d1b0drivers/net/xen-netfront.cdrivers/net/xen-netfront.c +4
-0@@ -566,15 +566,16 @@ static int xennet_start_xmit(struct sk_bif (notify)notify_remote_via_irq (np->netdev->irq); + np->stats.tx_bytes += skb->len; + np->stats.tx_packets++; + +/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ xennet_tx_buf_gc (dev);
drivers/net/xen-netfront.c static int xennet_start_xmit(struct sk_b · line 581
Quoted 10 lines
drivers/net/xen-netfront.c +0
-3if (!netfront_tx_slot_available (np))netif_stop_queue (dev);spin_unlock_irq (&np->tx_lock); - - np->stats.tx_bytes += skb->len; - np->stats.tx_packets++;return 0 ;
This moves the updating of both tx_bytes and tx_packets inside the spinlock, but as far as I can see we only _really_ need to move the tx_bytes update. Considering that we generally want to do as little work as possible while holding a lock, wouldn't the following be slightly better?
---
drivers/net/xen-netfront.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
drivers/net/xen-netfront.c +3 -1
@@ -566,6 +566,9 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)if (notify)notify_remote_via_irq (np->netdev->irq); + np->stats.tx_bytes += skb->len; + +/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ xennet_tx_buf_gc (dev);if (!netfront_tx_slot_available (np))
@@ -573,7 +576,6 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)spin_unlock_irq (&np->tx_lock); - np->stats.tx_bytes += skb->len; np->stats.tx_packets++;return 0 ;
Quoted 6 lines · Jesper Juhl
This moves the updating of both
tx_bytesandtx_packetsinside the spinlock, but as far as I can see we only _really_ need to move thetx_bytesupdate. Considering that we generally want to do as little work as possible while holding a lock, wouldn't the following be slightly better?
Hm, I think it would be better to keep them together. The second add is going to be pretty much free, particularly since the tx_bytes add will probably pull tx_packets into cache.
I have a followup patch to convert it to using the netdevice stats structure, which will definitely put them in the same cacheline (though perhaps the stats structure should group tx and rx members together?).
J
J
Jeff Garzik
AppliedQuoted 7 lines · Jeremy Fitzhardinge
xennet_tx_bug_gccan free the skb before we use it, so make sure we don't.Jeff, this is -rc material.
Signed-off-by Keir Fraser <[email protected]>Signed-off-by Jeremy Fitzhardinge <[email protected]>Cc Jeff Garzik <[email protected]>
applied