Thread (6 messages) 6 messages, 3 authors, 10d ago
COOLING10d

[RFC PATCH net-next] netpoll: hold RCU while walking napi_list

From: Runyu Xiao <hidden>
Date: 2026-06-27 10:17:46
Also in: lkml
Subsystem: networking [general], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

poll_napi() walks dev->napi_list with list_for_each_entry_rcu(). Some
netpoll send paths are already inside an RCU read-side section, but the
helper itself does not document or enforce that contract.

CONFIG_PROVE_RCU_LIST reports the poll_napi() traversal when the helper
is exercised directly from netpoll_poll_dev(). The current source has
important lifetime defenses around NAPI deletion and netpoll device
close, so this is not presented as a proven use-after-free. The issue is
that the RCU-list reader contract is implicit at the helper boundary.

Take rcu_read_lock() locally while walking the NAPI list. This keeps the
contract with netif_napi_del() and synchronize_net() explicit and avoids
relying on every current or future caller to provide the read-side
section.

This was found by our static analysis tool and then manually reviewed
against the current tree. CONFIG_PROVE_RCU_LIST was used as
target-matched triage evidence; the RFC is limited to making the
helper's RCU-list reader contract explicit.

This is an RFC because maintainers may prefer to express the existing
netpoll dev_lock/NAPI-list lifetime contract instead of adding a local
RCU reader around the polling loop.

Signed-off-by: Runyu Xiao <redacted>
---
 net/core/netpoll.c | 2 ++
 1 file changed, 2 insertions(+)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 5af14f14a362..2e13ca0d09fe 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -165,12 +165,14 @@ static void poll_napi(struct net_device *dev)
 	struct napi_struct *napi;
 	int cpu = smp_processor_id();
 
+	rcu_read_lock();
 	list_for_each_entry_rcu(napi, &dev->napi_list, dev_list) {
 		if (cmpxchg(&napi->poll_owner, -1, cpu) == -1) {
 			poll_one_napi(napi);
 			smp_store_release(&napi->poll_owner, -1);
 		}
 	}
+	rcu_read_unlock();
 }
 
 void netpoll_poll_dev(struct net_device *dev)
-- 
2.34.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help