summary refs log tree commit diff
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-10-29 21:28:59 -0700
committerDavid S. Miller <davem@davemloft.net>2009-10-29 21:28:59 -0700
commit0519d83d83ed485b5a1f9222ff69d7d6c9bb8a01 (patch)
tree2e336be8a4bd2e59bcd4b69b00feb77c6672a9cb /drivers/net/virtio_net.c
parent38bfd8f5bec496e8e0db8849e01c99a33479418a (diff)
parentb5dd884e682cae6b8c037f9d11f3b623b4cf2011 (diff)
downloadlinux-0519d83d83ed485b5a1f9222ff69d7d6c9bb8a01.tar.gz
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e78486504d3a..95274678fe45 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -514,8 +514,7 @@ again:
 	/* Free up any pending old buffers before queueing new ones. */
 	free_old_xmit_skbs(vi);
 
-	/* Put new one in send queue and do transmit */
-	__skb_queue_head(&vi->send, skb);
+	/* Try to transmit */
 	capacity = xmit_skb(vi, skb);
 
 	/* This can happen with OOM and indirect buffers. */
@@ -529,8 +528,17 @@ again:
 		}
 		return NETDEV_TX_BUSY;
 	}
-
 	vi->svq->vq_ops->kick(vi->svq);
+
+	/*
+	 * Put new one in send queue.  You'd expect we'd need this before
+	 * xmit_skb calls add_buf(), since the callback can be triggered
+	 * immediately after that.  But since the callback just triggers
+	 * another call back here, normal network xmit locking prevents the
+	 * race.
+	 */
+	__skb_queue_head(&vi->send, skb);
+
 	/* Don't wait up for transmitted skbs to be freed. */
 	skb_orphan(skb);
 	nf_reset(skb);