From: Longjun Tang When CONFIG_NET_RX_BUSY_POLL==Y and net.core.busy_read > 0, the __napi_busy_loop function calls napi_poll to perform busy polling, such as in the case of virtio_net's virnet_poll. If interrupts are enabled during the busy polling process, it is possible that data has already been received and that last_used_idx is updated before the interrupt is handled. This can lead to the vring_interrupt returning IRQ_NONE in response to the interrupt because used_idx == last_used_idx, which is considered a spurious interrupt.Once certain conditions are met, this interrupt can be disabled. The local_bh_enable during the busy polling process allows softirq to be executed and interrupt notification to be enabled. Removing local_bh_enable will significantly reduce the number of unhandled interrupts. Signed-off-by: Longjun Tang --- net/core/dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 5a3c0f40a93f..f5737c551666 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6763,12 +6763,12 @@ static void __napi_busy_loop(unsigned int napi_id, LINUX_MIB_BUSYPOLLRXPACKETS, work); skb_defer_free_flush(this_cpu_ptr(&softnet_data)); bpf_net_ctx_clear(bpf_net_ctx); - local_bh_enable(); if (!loop_end || loop_end(loop_end_arg, start_time)) break; if (unlikely(need_resched())) { + local_bh_enable(); if (flags & NAPI_F_END_ON_RESCHED) break; if (napi_poll) @@ -6784,6 +6784,7 @@ static void __napi_busy_loop(unsigned int napi_id, } cpu_relax(); } + local_bh_enable(); if (napi_poll) busy_poll_stop(napi, have_poll_lock, flags, budget); if (!IS_ENABLED(CONFIG_PREEMPT_RT)) -- 2.48.1