Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bnxt_en: Fix netdev locking in ULP IRQ functions

netdev_lock is already held when calling bnxt_ulp_irq_stop() and
bnxt_ulp_irq_restart(). When converting rtnl_lock to netdev_lock,
the original code was rtnl_dereference() to indicate that rtnl_lock
was already held. rcu_dereference_protected() is the correct
conversion after replacing rtnl_lock with netdev_lock.

Add a new helper netdev_lock_dereference() similar to
rtnl_dereference().

Fixes: 004b5008016a ("eth: bnxt: remove most dependencies on RTNL")
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250519204130.3097027-2-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Michael Chan and committed by
Jakub Kicinski
aed031da 48a62855

+6 -6
+3 -6
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
··· 20 20 #include <asm/byteorder.h> 21 21 #include <linux/bitmap.h> 22 22 #include <linux/auxiliary_bus.h> 23 + #include <net/netdev_lock.h> 23 24 24 25 #include "bnxt_hsi.h" 25 26 #include "bnxt.h" ··· 310 309 if (!ulp->msix_requested) 311 310 return; 312 311 313 - netdev_lock(bp->dev); 314 - ops = rcu_dereference(ulp->ulp_ops); 312 + ops = netdev_lock_dereference(ulp->ulp_ops, bp->dev); 315 313 if (!ops || !ops->ulp_irq_stop) 316 314 return; 317 315 if (test_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) 318 316 reset = true; 319 317 ops->ulp_irq_stop(ulp->handle, reset); 320 - netdev_unlock(bp->dev); 321 318 } 322 319 } 323 320 ··· 334 335 if (!ulp->msix_requested) 335 336 return; 336 337 337 - netdev_lock(bp->dev); 338 - ops = rcu_dereference(ulp->ulp_ops); 338 + ops = netdev_lock_dereference(ulp->ulp_ops, bp->dev); 339 339 if (!ops || !ops->ulp_irq_restart) 340 340 return; 341 341 ··· 346 348 bnxt_fill_msix_vecs(bp, ent); 347 349 } 348 350 ops->ulp_irq_restart(ulp->handle, ent); 349 - netdev_unlock(bp->dev); 350 351 kfree(ent); 351 352 } 352 353 }
+3
include/net/netdev_lock.h
··· 98 98 &qdisc_xmit_lock_key); \ 99 99 } 100 100 101 + #define netdev_lock_dereference(p, dev) \ 102 + rcu_dereference_protected(p, lockdep_is_held(&(dev)->lock)) 103 + 101 104 int netdev_debug_event(struct notifier_block *nb, unsigned long event, 102 105 void *ptr); 103 106