From: Kohei Enju Date: Fri, 20 Feb 2026 11:09:17 +0000 (+0000) Subject: net: core: allow netdev_upper_get_next_dev_rcu from bh context X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=39feb171f361f887dad8504dc5822b852871ac21;p=thirdparty%2Fkernel%2Flinux.git net: core: allow netdev_upper_get_next_dev_rcu from bh context Since XDP programs are called from a NAPI poll context, the RCU reference liveness is ensured by local_bh_disable(). Commit aeea1b86f936 ("bpf, devmap: Exclude XDP broadcast to master device") started to call netdev_upper_get_next_dev_rcu() from this context, but missed adding rcu_read_lock_bh_held() as a condition to the RCU checks. While both bh_disabled and rcu_read_lock() provide RCU protection, lockdep complains since the check condition is insufficient [1]. Add rcu_read_lock_bh_held() as condition to help lockdep to understand the dereference is safe, in the same way as commit 694cea395fde ("bpf: Allow RCU-protected lookups to happen from bh context"). [1] WARNING: net/core/dev.c:8099 at netdev_upper_get_next_dev_rcu+0x96/0xd0, CPU#0: swapper/0/0 ... RIP: 0010:netdev_upper_get_next_dev_rcu+0x96/0xd0 ... dev_map_enqueue_multi+0x411/0x970 xdp_do_redirect+0xdf2/0x1030 __igc_xdp_run_prog+0x6a0/0xc80 igc_poll+0x34b0/0x70b0 __napi_poll.constprop.0+0x98/0x490 net_rx_action+0x8f2/0xfa0 handle_softirqs+0x1c7/0x710 __irq_exit_rcu+0xb1/0xf0 irq_exit_rcu+0x9/0x20 common_interrupt+0x7f/0x90 Signed-off-by: Kohei Enju Acked-by: Martin KaFai Lau Link: https://patch.msgid.link/20260220110922.94781-1-kohei@enjuk.jp Signed-off-by: Jakub Kicinski --- diff --git a/net/core/dev.c b/net/core/dev.c index 1cf3ad840697e..19b84eaa26432 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -8113,7 +8113,8 @@ struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, { struct netdev_adjacent *upper; - WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held()); + WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held() && + !lockdep_rtnl_is_held()); upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list);