git: 9330b2f73c04 - main - if_bnxt: Fix HWRM mailbox/DMA teardown race on detach
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 09 Oct 2026 10:12:42 UTC
The branch main has been updated by ssaxena:
URL: https://cgit.FreeBSD.org/src/commit/?id=9330b2f73c04f06e39da5cf2279682a607185601
commit 9330b2f73c04f06e39da5cf2279682a607185601
Author: Sumit Saxena <sumit.saxena@broadcom.com>
AuthorDate: 2026-07-31 15:43:59 +0000
Commit: Sumit Saxena <ssaxena@FreeBSD.org>
CommitDate: 2026-10-09 08:24:43 +0000
if_bnxt: Fix HWRM mailbox/DMA teardown race on detach
iflib's generic device-deregister path never drains the admin task
before calling IFDI_DETACH, so bnxt_update_admin_status() (scheduled
once/sec) could still run concurrently with bnxt_detach(), racing on
softc->hwrm_lock and the shared HWRM request/response DMA buffer that
bnxt_detach() destroys. That race could leave the firmware-side HWRM
mailbox inconsistent, surfacing as "Timeout sending HWRM_VER_GET" on
the next module load.
Add a softc->detached guard: set it as the first statement in
bnxt_detach(), and bail out of bnxt_update_admin_status() immediately
when it's set.
Reviewed by: gallatin
MFC after: 2 weeks
Sponsored by: Broadcom Inc.
Differential Revision: https://reviews.freebsd.org/D58607
---
sys/dev/bnxt/bnxt_en/bnxt.h | 3 +++
sys/dev/bnxt/bnxt_en/if_bnxt.c | 8 ++++++++
2 files changed, 11 insertions(+)
diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h
index f0b9d114ad72..e50c4157ac0b 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt.h
@@ -1350,6 +1350,9 @@ struct bnxt_softc {
struct bnxt_nvram_info *nvm_info;
bool wol;
bool is_dev_init;
+ /* Cross-thread flag; access only via atomic_load_acq_int()/
+ * atomic_store_rel_int(), never as a plain bool. */
+ volatile int detached;
struct bnxt_hw_lro hw_lro;
uint8_t wol_filter_id;
uint16_t rx_coal_usecs;
diff --git a/sys/dev/bnxt/bnxt_en/if_bnxt.c b/sys/dev/bnxt/bnxt_en/if_bnxt.c
index f179250ebbe0..2ea1fc97fd92 100644
--- a/sys/dev/bnxt/bnxt_en/if_bnxt.c
+++ b/sys/dev/bnxt/bnxt_en/if_bnxt.c
@@ -3202,6 +3202,11 @@ bnxt_detach(if_ctx_t ctx)
struct bnxt_vlan_tag *tmp;
int i;
+ /* Set first: the admin task isn't drained before IFDI_DETACH and can
+ * still fire concurrently, so it must see this immediately via
+ * atomic_store_rel_int()/atomic_load_acq_int(). */
+ atomic_store_rel_int(&softc->detached, 1);
+
bnxt_mpc_irq_cleanup(softc);
bnxt_rdma_aux_device_uninit(softc);
cancel_delayed_work_sync(&softc->fw_reset_task);
@@ -4217,6 +4222,9 @@ bnxt_update_admin_status(if_ctx_t ctx)
if (!BNXT_PF(softc))
return;
+ if (atomic_load_acq_int(&softc->detached))
+ return;
+
bnxt_hwrm_port_qstats(softc);
if (BNXT_CHIP_P5_PLUS(softc) &&