At 2026-04-03 10:57:58, "Jason Wang" <[email protected]> wrote: >On Tue, Mar 31, 2026 at 6:27 PM Longjun Tang <[email protected]> wrote: >> >> From: Longjun Tang <[email protected]> >> >> virtnet_poll() is shared between NAPI softirq context and the busy-poll >> path (sk_busy_loop). In the busy-poll path the caller drives the loop >> directly and does not rely on interrupts to schedule NAPI; keeping >> callbacks enabled is wasteful and risks a flood of IRQ_NONE returns that >> can trigger the kernel's spurious-IRQ detector. >> >> Signed-off-by: Longjun Tang <[email protected]> >> --- >> drivers/net/virtio_net.c | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c >> index 72d6a9c6a5a2..df365fba2c40 100644 >> --- a/drivers/net/virtio_net.c >> +++ b/drivers/net/virtio_net.c >> @@ -3078,6 +3078,9 @@ static int virtnet_poll(struct napi_struct *napi, int >> budget) >> unsigned int xdp_xmit = 0; >> bool napi_complete; >> >> + if (READ_ONCE(napi->state) & NAPIF_STATE_IN_BUSY_POLL) >> + virtqueue_disable_cb(rq->vq); >> + > >I guess the root cause is virtuqeue_disable_cb() doesn't disable cb in >this case? > >static void virtqueue_napi_schedule(struct napi_struct *napi, > struct virtqueue *vq) >{ > if (napi_schedule_prep(napi)) { >virtqueue_disable_cb(vq); > __napi_schedule(napi); > } >} > >If there's an interrupt in the middle of NAPIF_STATE_IN_BUSY_POLL, >napi_schedule_prep() will return false, so we lose the chance to >disable cb. >
Sorry for the late reply! Regarding the root cause you mentioned, the chance to disable cb is indeed lost when the following three conditions are met: 1. In NAPIF_STATE_IN_BUSY_POLL 2. Interrupt occurs 3. more_used returns true However, in another scenario: 1. In NAPIF_STATE_IN_BUSY_POLL 2. Interrupt occurs 3. more_used returns false In this second scenario, there is no chance to disable cb during the execution of the virtnet_poll until virtqueue_napi_complete. >Thanks > >> virtnet_poll_cleantx(rq, budget); >> >> received = virtnet_receive(rq, budget, &xdp_xmit); >> -- >> 2.43.0 >>
