diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2021-04-13 07:38:08 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2021-07-03 10:51:17 +0200 |
commit | 22bc63c58e876cc359d0b1566dee3db8ecc16722 (patch) | |
tree | 1c33db49b994b50b7370a647959e7ee29ceebf9d /drivers/net/virtio_net.c | |
parent | virtio_net: move tx vq operation under tx queue lock (diff) | |
download | linux-22bc63c58e876cc359d0b1566dee3db8ecc16722.tar.xz linux-22bc63c58e876cc359d0b1566dee3db8ecc16722.zip |
virtio_net: move txq wakeups under tx q lock
We currently check num_free outside tx q lock
which is unsafe: new packets can arrive meanwhile
and there won't be space in the queue.
Thus a spurious queue wakeup causing overhead
and even packet drops.
Move the check under the lock to fix that.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9573f7622ef6..613aef630cdd 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1517,11 +1517,12 @@ static void virtnet_poll_cleantx(struct receive_queue *rq) if (__netif_tx_trylock(txq)) { free_old_xmit_skbs(sq, true); + + if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) + netif_tx_wake_queue(txq); + __netif_tx_unlock(txq); } - - if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) - netif_tx_wake_queue(txq); } static int virtnet_poll(struct napi_struct *napi, int budget) @@ -1606,6 +1607,9 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget) virtqueue_disable_cb(sq->vq); free_old_xmit_skbs(sq, true); + if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) + netif_tx_wake_queue(txq); + opaque = virtqueue_enable_cb_prepare(sq->vq); done = napi_complete_done(napi, 0); @@ -1626,9 +1630,6 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget) } } - if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) - netif_tx_wake_queue(txq); - return 0; } |