bnxt_en: suspicious RCU usage in bnxt_fw_reset_task() qdisc path in 7.1-rc6
Subsystems (2)
I am hitting a "suspicious RCU usage" lockdep splat from bnxt_en during a firmware reset on v7.1-rc6 (e43ffb69e043) with PROVE_RCU and PROVE_LOCKING enabled.
The firmware reset path re-opens the device from bnxt_fw_reset_task() holding only the netdev instance lock (&dev->lock). bnxt_open() -> __bnxt_open_nic() -> bnxt_set_real_num_queues() -> netif_set_real_num_tx_queues() then walks the qdisc tree in dev_qdisc_change_real_num_tx(), which still dereferences dev->qdisc with rtnl_dereference() and therefore expects rtnl_lock to be held:
void dev_qdisc_change_real_num_tx(struct net_device *dev,
unsigned int new_real_tx)
{
struct Qdisc *qdisc = rtnl_dereference(dev->qdisc);
...
}Since only the instance lock is held in this path, lockdep complains.
Splat
-----
=============================
WARNING: suspicious RCU usage
7.1.0 #1 Tainted: G E
-----------------------------
net/sched/sch_generic.c:1416 suspicious rcu_dereference_protected() usage!
other info that might help us debug this:
rcu_scheduler_active = 2, debug_locks = 1
3 locks held by kworker/u208:1/13:
#0: ((wq_completion)bnxt_pf_wq){+.+.}-{0:0}, at: process_scheduled_works+0x8f7/0x13b0 #1: ((work_completion)(&(&bp->fw_reset_task)->work)){+.+.}-{0:0}, at: process_scheduled_works+0x917/0x13b0 #2: (&dev->lock){+.+.}-{4:4}, at: bnxt_fw_reset_task+0x7ed/0x1e80
stack backtrace: CPU: 38 UID: 0 PID: 13 Comm: kworker/u208:1 Tainted: G E Hardware name: Wiwynn Delta Lake MP/Delta Lake-Class1, BIOS Y3DL405 11/21/2025 Workqueue: bnxt_pf_wq bnxt_fw_reset_task <TASK> dump_stack_lvl+0x69/0xa0 lockdep_rcu_suspicious+0x13f/0x1d0 dev_qdisc_change_real_num_tx+0x54/0xe0 netif_set_real_num_tx_queues+0x4ed/0xa80 __bnxt_open_nic+0x9cb/0x3490 ? bnxt_hwrm_if_change+0x4fd/0x620 bnxt_open+0x1cb/0x370 bnxt_fw_reset_task+0x80d/0x1e80 process_scheduled_works+0x9c1/0x13b0 worker_thread+0x90d/0xd20 kthread+0x320/0x3f0 ret_from_fork+0x2b6/0xb00 ret_from_fork_asm+0x11/0x20 </TASK>
Bisect / analysis
-----------------
This looks like a regression from:
850d9248d2ea ("Revert "bnxt_en: bring back rtnl_lock() in the
bnxt_open() path"")
That revert dropped rtnl_lock() from the bnxt_open() paths and left bnxt_fw_reset_task() holding only the instance lock around bnxt_open().
I can send a patch restoring rtnl_lock() around the bnxt_open() call in bnxt_fw_reset_task() (re-taking rtnl before the instance lock, matching the pre-revert code), but I wanted to report it first to make sure I am in the right direction.
Please let me know how you would like to proceed.
Thanks,
Breno
Quoted 67 lines · Breno Leitao
I am hitting a "suspicious RCU usage" lockdep splat from
bnxt_enduring a firmware reset on v7.1-rc6 (e43ffb69e043) withPROVE_RCUandPROVE_LOCKINGenabled.The firmware reset path re-opens the device from
bnxt_fw_reset_task()holding only the netdev instance lock (&dev->lock).bnxt_open()->__bnxt_open_nic()->bnxt_set_real_num_queues()->netif_set_real_num_tx_queues()then walks the qdisc tree indev_qdisc_change_real_num_tx(), which still dereferencesdev->qdiscwithrtnl_dereference()and therefore expectsrtnl_lockto be held:void dev_qdisc_change_real_num_tx(struct net_device *dev, unsigned int new_real_tx) { struct Qdisc *qdisc = rtnl_dereference(dev->qdisc); ... }Since only the instance lock is held in this path, lockdep complains.
Splat
-----=============================
WARNING: suspicious RCU usage
7.1.0 #1 Tainted: G E
-----------------------------
net/sched/sch_generic.c:1416suspiciousrcu_dereference_protected()usage!other info that might help us debug this:
rcu_scheduler_active= 2,debug_locks= 1
3 locks held by kworker/u208:1/13:#0: ((wq_completion)bnxt_pf_wq){+.+.}-{0:0}, at: process_scheduled_works+0x8f7/0x13b0 #1: ((work_completion)(&(&bp->fw_reset_task)->work)){+.+.}-{0:0}, at: process_scheduled_works+0x917/0x13b0 #2: (&dev->lock){+.+.}-{4:4}, at: bnxt_fw_reset_task+0x7ed/0x1e80 stack backtrace: CPU: 38 UID: 0 PID: 13 Comm: kworker/u208:1 Tainted: G E Hardware name: Wiwynn Delta Lake MP/Delta Lake-Class1, BIOS Y3DL405 11/21/2025 Workqueue: bnxt_pf_wq bnxt_fw_reset_task <TASK> dump_stack_lvl+0x69/0xa0 lockdep_rcu_suspicious+0x13f/0x1d0 dev_qdisc_change_real_num_tx+0x54/0xe0 netif_set_real_num_tx_queues+0x4ed/0xa80 __bnxt_open_nic+0x9cb/0x3490 ? bnxt_hwrm_if_change+0x4fd/0x620 bnxt_open+0x1cb/0x370 bnxt_fw_reset_task+0x80d/0x1e80 process_scheduled_works+0x9c1/0x13b0 worker_thread+0x90d/0xd20 kthread+0x320/0x3f0 ret_from_fork+0x2b6/0xb00 ret_from_fork_asm+0x11/0x20 </TASK>Bisect / analysis
-----------------This looks like a regression from:
850d9248d2ea("Revert "bnxt_en: bring backrtnl_lock()in thebnxt_open() path"")That revert dropped
rtnl_lock()from thebnxt_open()paths and leftbnxt_fw_reset_task()holding only the instance lock aroundbnxt_open().
Quoted 6 lines
I can send a patch restoring
rtnl_lock()around thebnxt_open()call inbnxt_fw_reset_task()(re-taking rtnl before the instance lock, matching the pre-revert code), but I wanted to report it first to make sure I am in the right direction.Please let me know how you would like to proceed.
I hope (but need to verify) that at this point most of the paths that assign qdisc are under ops lock as well. So the alternative might be to use netdev_ops_lock_dereference from Jakub's recent
https://lore.kernel.org/netdev/[email protected]/t/#m3de56e1d53f86b2c1b12ca29d1617dd6635e78cb
Quoted 73 lines · Stanislav Fomichev
Quoted 72 lines · Breno Leitao
I am hitting a "suspicious RCU usage" lockdep splat from
bnxt_enduring a firmware reset on v7.1-rc6 (e43ffb69e043) withPROVE_RCUandPROVE_LOCKINGenabled.The firmware reset path re-opens the device from
bnxt_fw_reset_task()holding only the netdev instance lock (&dev->lock).bnxt_open()->__bnxt_open_nic()->bnxt_set_real_num_queues()->netif_set_real_num_tx_queues()then walks the qdisc tree indev_qdisc_change_real_num_tx(), which still dereferencesdev->qdiscwithrtnl_dereference()and therefore expectsrtnl_lockto be held:void dev_qdisc_change_real_num_tx(struct net_device *dev, unsigned int new_real_tx) { struct Qdisc *qdisc = rtnl_dereference(dev->qdisc); ... }Since only the instance lock is held in this path, lockdep complains.
Splat
-----=============================
WARNING: suspicious RCU usage
7.1.0 #1 Tainted: G E
-----------------------------
net/sched/sch_generic.c:1416suspiciousrcu_dereference_protected()usage!other info that might help us debug this:
rcu_scheduler_active= 2,debug_locks= 1
3 locks held by kworker/u208:1/13:#0: ((wq_completion)bnxt_pf_wq){+.+.}-{0:0}, at: process_scheduled_works+0x8f7/0x13b0 #1: ((work_completion)(&(&bp->fw_reset_task)->work)){+.+.}-{0:0}, at: process_scheduled_works+0x917/0x13b0 #2: (&dev->lock){+.+.}-{4:4}, at: bnxt_fw_reset_task+0x7ed/0x1e80 stack backtrace: CPU: 38 UID: 0 PID: 13 Comm: kworker/u208:1 Tainted: G E Hardware name: Wiwynn Delta Lake MP/Delta Lake-Class1, BIOS Y3DL405 11/21/2025 Workqueue: bnxt_pf_wq bnxt_fw_reset_task <TASK> dump_stack_lvl+0x69/0xa0 lockdep_rcu_suspicious+0x13f/0x1d0 dev_qdisc_change_real_num_tx+0x54/0xe0 netif_set_real_num_tx_queues+0x4ed/0xa80 __bnxt_open_nic+0x9cb/0x3490 ? bnxt_hwrm_if_change+0x4fd/0x620 bnxt_open+0x1cb/0x370 bnxt_fw_reset_task+0x80d/0x1e80 process_scheduled_works+0x9c1/0x13b0 worker_thread+0x90d/0xd20 kthread+0x320/0x3f0 ret_from_fork+0x2b6/0xb00 ret_from_fork_asm+0x11/0x20 </TASK>Bisect / analysis
-----------------This looks like a regression from:
850d9248d2ea("Revert "bnxt_en: bring backrtnl_lock()in thebnxt_open() path"")That revert dropped
rtnl_lock()from thebnxt_open()paths and leftbnxt_fw_reset_task()holding only the instance lock aroundbnxt_open().I can send a patch restoring
rtnl_lock()around thebnxt_open()call inbnxt_fw_reset_task()(re-taking rtnl before the instance lock, matching the pre-revert code), but I wanted to report it first to make sure I am in the right direction.
Quoted 6 lines
Quoted 1 line
Please let me know how you would like to proceed.
I hope (but need to verify) that at this point most of the paths that assign qdisc are under ops lock as well. So the alternative might be to use
netdev_ops_lock_dereferencefrom Jakub's recent
https://lore.kernel.org/netdev/[email protected]/t/#m3de56e1d53f86b2c1b12ca29d1617dd6635e78cb
Agree with Jakub, this is more than just the assignment :-(
Jakub Kicinski
maintainerQuoted 5 lines · On Tue, 2 Jun 2026 08:33:31 -0700 Breno Leitao wrote:
This looks like a regression from:
850d9248d2ea("Revert "bnxt_en: bring backrtnl_lock()in thebnxt_open() path"")
Quoted 7 lines
That revert dropped
rtnl_lock()from thebnxt_open()paths and leftbnxt_fw_reset_task()holding only the instance lock aroundbnxt_open().I can send a patch restoring
rtnl_lock()around thebnxt_open()call inbnxt_fw_reset_task()(re-taking rtnl before the instance lock, matching the pre-revert code), but I wanted to report it first to make sure I am in the right direction.
Yes, we need to revert the revert. Per my recent ethtool locking series netif_set_num_tx_queues needs rtnl_lock for now.
Quoted 9 lines · Jakub Kicinski
Quoted 8 lines · On Tue, 2 Jun 2026 08:33:31 -0700 Breno Leitao wrote:
This looks like a regression from:
850d9248d2ea("Revert "bnxt_en: bring backrtnl_lock()in thebnxt_open() path"")That revert dropped
rtnl_lock()from thebnxt_open()paths and leftbnxt_fw_reset_task()holding only the instance lock aroundbnxt_open().
Quoted 7 lines
Quoted 4 lines
I can send a patch restoring
rtnl_lock()around thebnxt_open()call inbnxt_fw_reset_task()(re-taking rtnl before the instance lock, matching the pre-revert code), but I wanted to report it first to make sure I am in the right direction.Yes, we need to revert the revert. Per my recent ethtool locking series
netif_set_num_tx_queuesneedsrtnl_lockfor now.
Ack and thanks for the direction. Do you want me to do it, or, is it someone is already taking care of?
Thanks
--breno
Jakub Kicinski
maintainerQuoted 15 lines · On Wed, 3 Jun 2026 04:43:01 -0700 Breno Leitao wrote:
Quoted 14 lines · Jakub Kicinski
Quoted 12 lines · On Tue, 2 Jun 2026 08:33:31 -0700 Breno Leitao wrote:
This looks like a regression from:
850d9248d2ea("Revert "bnxt_en: bring backrtnl_lock()in thebnxt_open() path"")That revert dropped
rtnl_lock()from thebnxt_open()paths and leftbnxt_fw_reset_task()holding only the instance lock aroundbnxt_open().I can send a patch restoring
rtnl_lock()around thebnxt_open()call inbnxt_fw_reset_task()(re-taking rtnl before the instance lock, matching the pre-revert code), but I wanted to report it first to make sure I am in the right direction.
Quoted 5 lines
Quoted 2 lines
Yes, we need to revert the revert. Per my recent ethtool locking series
netif_set_num_tx_queuesneedsrtnl_lockfor now.Ack and thanks for the direction. Do you want me to do it, or, is it someone is already taking care of?
I'll send it out and CC y'all. Stan points out that full revert may not be necessary..