Skip to content

Commit a7766ef

Browse files
committed
virtio_net: disable cb aggressively
There are currently two cases where we poll TX vq not in response to a callback: start xmit and rx napi. We currently do this with callbacks enabled which can cause extra interrupts from the card. Used not to be a big issue as we run with interrupts disabled but that is no longer the case, and in some cases the rate of spurious interrupts is so high linux detects this and actually kills the interrupt. Fix up by disabling the callbacks before polling the tx vq. Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent 8d622d2 commit a7766ef

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

drivers/net/virtio_net.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,7 +1516,10 @@ static void virtnet_poll_cleantx(struct receive_queue *rq)
15161516
return;
15171517

15181518
if (__netif_tx_trylock(txq)) {
1519-
free_old_xmit_skbs(sq, true);
1519+
do {
1520+
virtqueue_disable_cb(sq->vq);
1521+
free_old_xmit_skbs(sq, true);
1522+
} while (unlikely(!virtqueue_enable_cb_delayed(sq->vq)));
15201523

15211524
if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS)
15221525
netif_tx_wake_queue(txq);
@@ -1691,10 +1694,14 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
16911694
bool use_napi = sq->napi.weight;
16921695

16931696
/* Free up any pending old buffers before queueing new ones. */
1694-
free_old_xmit_skbs(sq, false);
1697+
do {
1698+
if (use_napi)
1699+
virtqueue_disable_cb(sq->vq);
1700+
1701+
free_old_xmit_skbs(sq, false);
16951702

1696-
if (use_napi && kick)
1697-
virtqueue_enable_cb_delayed(sq->vq);
1703+
} while (use_napi && kick &&
1704+
unlikely(!virtqueue_enable_cb_delayed(sq->vq)));
16981705

16991706
/* timestamp packet in software */
17001707
skb_tx_timestamp(skb);

0 commit comments

Comments
 (0)