Skip to content

Commit 1e20324

Browse files
committed
virtio-net: don't re-enable refill work too early when NAPI is disabled
Commit 4bc1281 ("virtio-net: disable delayed refill when pausing rx") fixed a deadlock between reconfig paths and refill work trying to disable the same NAPI instance. The refill work can't run in parallel with reconfig because trying to double-disable a NAPI instance causes a stall under the instance lock, which the reconfig path needs to re-enable the NAPI and therefore unblock the stalled thread. There are two cases where we re-enable refill too early. One is in the virtnet_set_queues() handler. We call it when installing XDP: virtnet_rx_pause_all(vi); ... virtnet_napi_tx_disable(..); ... virtnet_set_queues(..); ... virtnet_rx_resume_all(..); We want the work to be disabled until we call virtnet_rx_resume_all(), but virtnet_set_queues() kicks it before NAPIs were re-enabled. The other case is a more trivial case of mis-ordering in __virtnet_rx_resume() found by code inspection. Taking the spin lock in virtnet_set_queues() (requested during review) may be unnecessary as we are under rtnl_lock and so are all paths writing to ->refill_enabled. Acked-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Bui Quang Minh <minhquangbui99@gmail.com> Fixes: 4bc1281 ("virtio-net: disable delayed refill when pausing rx") Fixes: 413f027 ("net: protect NAPI enablement with netdev_lock()") Link: https://patch.msgid.link/20250430163758.3029367-1-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 75dbdaa commit 1e20324

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

drivers/net/virtio_net.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3383,12 +3383,15 @@ static void __virtnet_rx_resume(struct virtnet_info *vi,
33833383
bool refill)
33843384
{
33853385
bool running = netif_running(vi->dev);
3386+
bool schedule_refill = false;
33863387

33873388
if (refill && !try_fill_recv(vi, rq, GFP_KERNEL))
3388-
schedule_delayed_work(&vi->refill, 0);
3389-
3389+
schedule_refill = true;
33903390
if (running)
33913391
virtnet_napi_enable(rq);
3392+
3393+
if (schedule_refill)
3394+
schedule_delayed_work(&vi->refill, 0);
33923395
}
33933396

33943397
static void virtnet_rx_resume_all(struct virtnet_info *vi)
@@ -3728,8 +3731,10 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
37283731
succ:
37293732
vi->curr_queue_pairs = queue_pairs;
37303733
/* virtnet_open() will refill when device is going to up. */
3731-
if (dev->flags & IFF_UP)
3734+
spin_lock_bh(&vi->refill_lock);
3735+
if (dev->flags & IFF_UP && vi->refill_enabled)
37323736
schedule_delayed_work(&vi->refill, 0);
3737+
spin_unlock_bh(&vi->refill_lock);
37333738

37343739
return 0;
37353740
}

0 commit comments

Comments
 (0)