diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 54bf0912b7373ec7bb6cfad5ffde55e1ba82203f..d9ebac8a2d99d8bc30a566ce1217a91bd1eee7db 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -517,8 +517,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) /* 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. */ @@ -532,8 +531,17 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) } 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);