From 8dc87fc5d6a0eb337744737008177342a708bf36 Mon Sep 17 00:00:00 2001 From: Maxime Chevallier Date: Thu, 29 Oct 2026 16:31:29 +0100 Subject: net: Use a dedicated flag to track disabled napi instances Trying to disable the napi threaded state while the napi instance is disabled will hang forever in napi_stop_kthread(), as it waits for NAPIF_STATE_SCHED_THREADED to clear. This won't happen until the next ____napi_schedule() call, which won't happen as it's disabled. This happens in 2 instances : - Drivers that create but don't use napi instances (stmmac's rxtx napi for AF_XDP for example), here it's a driver bug - Drivers that create their napi instances in .probe(). Here, setting threaded off while the interface is down will hang : ip link set eth0 down echo 1 > /sys/class/net/eth0/threaded echo 0 > /sys/class/net/eth0/threaded -> hang Checking on netif_running() isn't enough, as napi instances may be transiently disabled when changing the MTU for example, let's use a dedicated flag to track if the instance is disabled. This allows immediately disabling the kthread when the instance is disabled. This was tested on mvpp2 (probe-time napi_add) and stmmac. Fixes: 689883de94dd ("net: stop napi kthreads when THREADED napi is disabled") Tested-by: Daniel Machon Signed-off-by: Maxime Chevallier Link: https://patch.msgid.link/20261029153130.121204-1-maxime.chevallier@bootlin.com Signed-off-by: Jakub Kicinski --- include/linux/netdevice.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c0ae442c4344..435be7880d7e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -440,6 +440,7 @@ enum { NAPI_STATE_HAS_NOTIFIER, /* Napi has an IRQ notifier */ NAPI_STATE_THREADED_BUSY_POLL, /* The threaded NAPI poller will busy poll */ NAPI_STATE_PERCPU, /* NAPI handler is run per-CPU - incompatible with threaded mode */ + NAPI_STATE_DISABLED, /* NAPI is disabled */ }; enum { @@ -456,6 +457,7 @@ enum { NAPIF_STATE_HAS_NOTIFIER = BIT(NAPI_STATE_HAS_NOTIFIER), NAPIF_STATE_THREADED_BUSY_POLL = BIT(NAPI_STATE_THREADED_BUSY_POLL), NAPIF_STATE_PERCPU = BIT(NAPI_STATE_PERCPU), + NAPIF_STATE_DISABLED = BIT(NAPI_STATE_DISABLED), }; enum gro_result { -- cgit v1.2.3