* [RFC net v3 0/3] bnxt_en: Make RING FREE more robust
@ 2026-09-23 21:07 Joe Damato
2026-09-23 21:07 ` [RFC net v3 1/3] bnxt_en: return the RING_FREE status to callers Joe Damato
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Joe Damato @ 2026-09-23 21:07 UTC (permalink / raw)
To: netdev
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms,
michael.chan, pavan.chebbi, linux-kernel, Joe Damato
Greetings:
This is a follow up to the previous RFC (linked below), updated based on
feedback from Michael.
On two production systems, I saw the following dmesg pattern:
NETDEV WATCHDOG: transmit queue 0 timed out 6073 ms
Resp cmpl intr err msg: 0x51 x20
hwrm_ring_free type 1 failed x12
hwrm_ring_free type 2 failed x8
AMD-Vi: IO_PAGE_FAULT x3
This suggests that, for some currently unknown reason, TX completions stall
and the netdev watchdog fires. The driver asks FW to free the rings, this
times out, but the driver ignores the possible failure and frees ring memory.
Since the FW didn't respond to the ring free command, it is possible that the
FW is still DMAing to the memory which was freed.
This series tries to prevent this by:
- Returning and checking ring free command return values
- Examining the FW response if the ring free command times out. It is
possible that, for some reason, the FW did complete the ring free but was
unable to respond with an IRQ. This seems unlikely given what appears to be
a use after free in dmesg, but worth logging just in case.
- Lastly, stop DMA before the driver frees ring memory, which should prevent
any possible use after free.
Sending this as an RFC so that the Broadcom folks have some time to take a
look and test as needed.
Thanks,
Joe
v3:
- No changes to patch 1
- Patch 2: Don't poll for the valid bit as Michael suggested.
- Patch 3: bnxt_hwrm_ring_free now returns -EIO instead of stopping the
device, so the remaining resources can be freed and the remaining commands
can be sent before stopping the device, as Michael suggested. Note the
switch to using pci_clear_master in this patch instead of
pci_disable_device. This was done so that the normal shutdown paths can
call pci_disable_device without generating a warning.
v2: https://lore.kernel.org/netdev/20260922182405.1290749-1-joe@dama.to/
- No changes to patch 1
- Patch 2 from v1 dropped
- Patch 2 in the v2 now checks the response and logs state before giving up
- Patch 3 in the v2 disables the device to stop DMA before freeing ring
memory
RFCv1: https://lore.kernel.org/netdev/20260917233218.1160001-1-joe@dama.to/
Joe Damato (3):
bnxt_en: return the RING_FREE status to callers
bnxt_en: check HWRM response if completion never arrives
bnxt_en: stop DMA before releasing rings the firmware did not free
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 96 ++++++++++++-------
.../net/ethernet/broadcom/bnxt/bnxt_hwrm.c | 33 ++++++-
2 files changed, 91 insertions(+), 38 deletions(-)
base-commit: 17741334d00bf5ebd37f8c1c36bc9c146a351deb
--
2.53.0-Meta
^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC net v3 1/3] bnxt_en: return the RING_FREE status to callers
2026-09-23 21:07 [RFC net v3 0/3] bnxt_en: Make RING FREE more robust Joe Damato
@ 2026-09-23 21:07 ` Joe Damato
2026-09-23 21:07 ` [RFC net v3 2/3] bnxt_en: check HWRM response if completion never arrives Joe Damato
2026-09-23 21:07 ` [RFC net v3 3/3] bnxt_en: stop DMA before releasing rings the firmware did not free Joe Damato
2 siblings, 0 replies; 7+ messages in thread
From: Joe Damato @ 2026-09-23 21:07 UTC (permalink / raw)
To: netdev, Michael Chan, Pavan Chebbi, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Prashant Sreedharan
Cc: horms, linux-kernel, Joe Damato
hwrm_ring_free_send_msg() reports failure to its caller, returning -EIO
when the firmware rejects HWRM_RING_FREE or never answers it. All three
ring free helpers that send the command discard the value.
Return it instead. No caller acts on it yet, so there is no functional
change.
Fixes: 74608fc98d28 ("bnxt_en: Ring free response from close path should use completion ring")
Signed-off-by: Joe Damato <joe@dama.to>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 48 +++++++++++++----------
1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index d7728d0c5b6e..a7f6facca7b4 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -7660,50 +7660,55 @@ static int hwrm_ring_free_send_msg(struct bnxt *bp,
return 0;
}
-static void bnxt_hwrm_tx_ring_free(struct bnxt *bp,
- struct bnxt_tx_ring_info *txr,
- bool close_path)
+static int bnxt_hwrm_tx_ring_free(struct bnxt *bp,
+ struct bnxt_tx_ring_info *txr,
+ bool close_path)
{
struct bnxt_ring_struct *ring = &txr->tx_ring_struct;
u32 cmpl_ring_id;
+ int rc;
if (ring->fw_ring_id == INVALID_HW_RING_ID)
- return;
+ return 0;
cmpl_ring_id = close_path ? bnxt_cp_ring_for_tx(bp, txr) :
INVALID_HW_RING_ID;
- hwrm_ring_free_send_msg(bp, ring, RING_FREE_REQ_RING_TYPE_TX,
- cmpl_ring_id);
+ rc = hwrm_ring_free_send_msg(bp, ring, RING_FREE_REQ_RING_TYPE_TX,
+ cmpl_ring_id);
ring->fw_ring_id = INVALID_HW_RING_ID;
+ return rc;
}
-static void bnxt_hwrm_rx_ring_free(struct bnxt *bp,
- struct bnxt_rx_ring_info *rxr,
- bool close_path)
+static int bnxt_hwrm_rx_ring_free(struct bnxt *bp,
+ struct bnxt_rx_ring_info *rxr,
+ bool close_path)
{
struct bnxt_ring_struct *ring = &rxr->rx_ring_struct;
u32 grp_idx = rxr->bnapi->index;
u32 cmpl_ring_id;
+ int rc;
if (ring->fw_ring_id == INVALID_HW_RING_ID)
- return;
+ return 0;
cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr);
- hwrm_ring_free_send_msg(bp, ring,
- RING_FREE_REQ_RING_TYPE_RX,
- close_path ? cmpl_ring_id :
- INVALID_HW_RING_ID);
+ rc = hwrm_ring_free_send_msg(bp, ring,
+ RING_FREE_REQ_RING_TYPE_RX,
+ close_path ? cmpl_ring_id :
+ INVALID_HW_RING_ID);
ring->fw_ring_id = INVALID_HW_RING_ID;
bp->grp_info[grp_idx].rx_fw_ring_id = INVALID_HW_RING_ID;
+ return rc;
}
-static void bnxt_hwrm_rx_agg_ring_free(struct bnxt *bp,
- struct bnxt_rx_ring_info *rxr,
- bool close_path)
+static int bnxt_hwrm_rx_agg_ring_free(struct bnxt *bp,
+ struct bnxt_rx_ring_info *rxr,
+ bool close_path)
{
struct bnxt_ring_struct *ring = &rxr->rx_agg_ring_struct;
u32 grp_idx = rxr->bnapi->index;
u32 type, cmpl_ring_id;
+ int rc;
if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS)
type = RING_FREE_REQ_RING_TYPE_RX_AGG;
@@ -7711,14 +7716,15 @@ static void bnxt_hwrm_rx_agg_ring_free(struct bnxt *bp,
type = RING_FREE_REQ_RING_TYPE_RX;
if (ring->fw_ring_id == INVALID_HW_RING_ID)
- return;
+ return 0;
cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr);
- hwrm_ring_free_send_msg(bp, ring, type,
- close_path ? cmpl_ring_id :
- INVALID_HW_RING_ID);
+ rc = hwrm_ring_free_send_msg(bp, ring, type,
+ close_path ? cmpl_ring_id :
+ INVALID_HW_RING_ID);
ring->fw_ring_id = INVALID_HW_RING_ID;
bp->grp_info[grp_idx].agg_fw_ring_id = INVALID_HW_RING_ID;
+ return rc;
}
static void bnxt_hwrm_cp_ring_free(struct bnxt *bp,
--
2.53.0-Meta
^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC net v3 2/3] bnxt_en: check HWRM response if completion never arrives
2026-09-23 21:07 [RFC net v3 0/3] bnxt_en: Make RING FREE more robust Joe Damato
2026-09-23 21:07 ` [RFC net v3 1/3] bnxt_en: return the RING_FREE status to callers Joe Damato
@ 2026-09-23 21:07 ` Joe Damato
2026-09-23 21:07 ` [RFC net v3 3/3] bnxt_en: stop DMA before releasing rings the firmware did not free Joe Damato
2 siblings, 0 replies; 7+ messages in thread
From: Joe Damato @ 2026-09-23 21:07 UTC (permalink / raw)
To: netdev, Michael Chan, Pavan Chebbi, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Prashant Sreedharan
Cc: horms, linux-kernel, Joe Damato
When a command is sent over a completion ring, __hwrm_send() waits for
NAPI to consume the completion and gives up if it never arrives, without
looking at the response.
If a completion is not posted within the timeout, check the response
before giving up. If resp_len is set, the sequence id matches, and the
valid byte is set then the firmware completed the command and only the
notification was lost. Fall through to the normal error_code handling in
that case.
Several seconds are spent waiting for the completion, so a response that
was written at all is complete by the time the wait gives up. There is no
need to poll for the valid byte here the way the polling path below has
to, where the poll is for a non-zero length and the valid byte at the end
of the message may still be on its way.
Log the response state on both paths so there is more data when this rare
event occurs.
Fixes: 74608fc98d28 ("bnxt_en: Ring free response from close path should use completion ring")
Signed-off-by: Joe Damato <joe@dama.to>
---
.../net/ethernet/broadcom/bnxt/bnxt_hwrm.c | 33 ++++++++++++++++---
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
index 5bfabdca7d0e..4feba90f0bf6 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
@@ -582,11 +582,36 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
}
if (READ_ONCE(token->state) != BNXT_HWRM_COMPLETE) {
- hwrm_err(bp, ctx, "Resp cmpl intr err msg: 0x%x\n",
- req_type);
- goto exit;
+ __le16 resp_seq_id;
+ u8 valid_byte = 0;
+
+ /* The completion ring entry was not delivered for
+ * some reason. It might be possible that the command
+ * was carried out even without a completion being
+ * posted. Check the response before giving up and log
+ * the state.
+ */
+ dma_rmb();
+ resp_seq_id = READ_ONCE(ctx->resp->seq_id);
+ len = le16_to_cpu(READ_ONCE(ctx->resp->resp_len));
+ if (len && resp_seq_id == ctx->req->seq_id)
+ valid_byte = *((u8 *)ctx->resp + len - 1);
+
+ if (!valid_byte) {
+ hwrm_err(bp, ctx,
+ "Resp cmpl intr err msg: 0x%x len:%d seq:0x%x/0x%x\n",
+ req_type, len,
+ le16_to_cpu(resp_seq_id),
+ le16_to_cpu(ctx->req->seq_id));
+ goto exit;
+ }
+ netdev_warn(bp->dev,
+ "Resp cmpl intr not delivered, msg: 0x%x completed anyway (len:%d valid:0x%x err:0x%x)\n",
+ req_type, len, valid_byte,
+ le16_to_cpu(ctx->resp->error_code));
+ } else {
+ len = le16_to_cpu(READ_ONCE(ctx->resp->resp_len));
}
- len = le16_to_cpu(READ_ONCE(ctx->resp->resp_len));
valid = ((u8 *)ctx->resp) + len - 1;
} else {
__le16 seen_out_of_seq = ctx->req->seq_id; /* will never see */
--
2.53.0-Meta
^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC net v3 3/3] bnxt_en: stop DMA before releasing rings the firmware did not free
2026-09-23 21:07 [RFC net v3 0/3] bnxt_en: Make RING FREE more robust Joe Damato
2026-09-23 21:07 ` [RFC net v3 1/3] bnxt_en: return the RING_FREE status to callers Joe Damato
2026-09-23 21:07 ` [RFC net v3 2/3] bnxt_en: check HWRM response if completion never arrives Joe Damato
@ 2026-09-23 21:07 ` Joe Damato
2026-09-24 6:26 ` Michael Chan
2 siblings, 1 reply; 7+ messages in thread
From: Joe Damato @ 2026-09-23 21:07 UTC (permalink / raw)
To: netdev, Michael Chan, Pavan Chebbi, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Prashant Sreedharan
Cc: horms, linux-kernel, Joe Damato
When HWRM_RING_FREE is not answered, bnxt_hwrm_ring_free() clears
fw_ring_id and __bnxt_close_nic() goes on to call bnxt_free_mem(), which
unmaps the ring memory and the RX buffers that the FW may still be
using.
This is reachable in production. On a BCM57504 the first sign is the TX
watchdog; the close that follows times out a subset of its RING_FREEs and
the driver releases those rings anyway:
05:30:12 NETDEV WATCHDOG: transmit queue 0 timed out 6073 ms
05:30:12 Resp cmpl intr err msg: 0x51 x20
05:30:12 hwrm_ring_free type 1 failed x12
05:30:12 hwrm_ring_free type 2 failed x8
05:30:12 AMD-Vi: IO_PAGE_FAULT x3
Count the rings the firmware did not free and report that to the caller
so it can decide what to do. bnxt_hwrm_resource_free() still frees the
remaining firmware resources before returning the error, so the shutdown
can send every message it needs to before the device is stopped.
The device stays unusable until a firmware reset.
Fixes: 74608fc98d28 ("bnxt_en: Ring free response from close path should use completion ring")
Signed-off-by: Joe Damato <joe@dama.to>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 48 +++++++++++++++++------
1 file changed, 35 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index a7f6facca7b4..332fb374db5e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -7754,21 +7754,25 @@ static void bnxt_clear_one_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cp
memset(cpr->cp_desc_ring[i], 0, size);
}
-static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
+static int bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
{
+ int stuck = 0;
u32 type;
int i;
if (!bp->bnapi)
- return;
+ return 0;
for (i = 0; i < bp->tx_nr_rings; i++)
- bnxt_hwrm_tx_ring_free(bp, &bp->tx_ring[i], close_path);
+ if (bnxt_hwrm_tx_ring_free(bp, &bp->tx_ring[i], close_path))
+ stuck++;
bnxt_cancel_dim(bp);
for (i = 0; i < bp->rx_nr_rings; i++) {
- bnxt_hwrm_rx_ring_free(bp, &bp->rx_ring[i], close_path);
- bnxt_hwrm_rx_agg_ring_free(bp, &bp->rx_ring[i], close_path);
+ if (bnxt_hwrm_rx_ring_free(bp, &bp->rx_ring[i], close_path))
+ stuck++;
+ if (bnxt_hwrm_rx_agg_ring_free(bp, &bp->rx_ring[i], close_path))
+ stuck++;
}
/* The completion rings are about to be freed. After that the
@@ -7798,6 +7802,19 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
bp->grp_info[i].cp_fw_ring_id = INVALID_HW_RING_ID;
}
}
+
+ if (!stuck)
+ return 0;
+
+ netdev_err(bp->dev, "Firmware did not free %d ring(s)\n", stuck);
+ return -EIO;
+}
+
+static void bnxt_stop_dma(struct bnxt *bp)
+{
+ netdev_err(bp->dev,
+ "Disabling DMA before releasing ring memory, a firmware reset is required\n");
+ pci_clear_master(bp->pdev);
}
static int __bnxt_trim_rings(struct bnxt *bp, int *rx, int *tx, int max,
@@ -10832,16 +10849,19 @@ static void bnxt_clear_vnic(struct bnxt *bp)
bnxt_hwrm_vnic_ctx_free(bp);
}
-static void bnxt_hwrm_resource_free(struct bnxt *bp, bool close_path,
- bool irq_re_init)
+static int bnxt_hwrm_resource_free(struct bnxt *bp, bool close_path,
+ bool irq_re_init)
{
+ int rc;
+
bnxt_clear_vnic(bp);
- bnxt_hwrm_ring_free(bp, close_path);
+ rc = bnxt_hwrm_ring_free(bp, close_path);
bnxt_hwrm_ring_grp_free(bp);
if (irq_re_init) {
bnxt_hwrm_stat_ctx_free(bp);
bnxt_hwrm_free_tunnel_ports(bp);
}
+ return rc;
}
static int bnxt_hwrm_set_br_mode(struct bnxt *bp, u16 br_mode)
@@ -11363,15 +11383,15 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
return 0;
err_out:
- bnxt_hwrm_resource_free(bp, 0, true);
+ if (bnxt_hwrm_resource_free(bp, 0, true))
+ bnxt_stop_dma(bp);
return rc;
}
static int bnxt_shutdown_nic(struct bnxt *bp, bool irq_re_init)
{
- bnxt_hwrm_resource_free(bp, 1, irq_re_init);
- return 0;
+ return bnxt_hwrm_resource_free(bp, 1, irq_re_init);
}
static int bnxt_init_nic(struct bnxt *bp, bool irq_re_init)
@@ -13422,7 +13442,8 @@ int bnxt_half_open_nic(struct bnxt *bp)
*/
void bnxt_half_close_nic(struct bnxt *bp)
{
- bnxt_hwrm_resource_free(bp, false, true);
+ if (bnxt_hwrm_resource_free(bp, false, true))
+ bnxt_stop_dma(bp);
bnxt_del_napi(bp);
bnxt_free_skbs(bp);
bnxt_free_mem(bp, true);
@@ -13501,7 +13522,8 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init,
if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp))
bnxt_clear_rss_ctxs(bp);
/* Flush rings and disable interrupts */
- bnxt_shutdown_nic(bp, irq_re_init);
+ if (bnxt_shutdown_nic(bp, irq_re_init))
+ bnxt_stop_dma(bp);
/* TODO CHIMP_FW: Link/PHY related cleanup if (link_re_init) */
--
2.53.0-Meta
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC net v3 3/3] bnxt_en: stop DMA before releasing rings the firmware did not free
2026-09-23 21:07 ` [RFC net v3 3/3] bnxt_en: stop DMA before releasing rings the firmware did not free Joe Damato
@ 2026-09-24 6:26 ` Michael Chan
2026-09-24 17:41 ` Joe Damato
0 siblings, 1 reply; 7+ messages in thread
From: Michael Chan @ 2026-09-24 6:26 UTC (permalink / raw)
To: Joe Damato
Cc: netdev, Pavan Chebbi, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Prashant Sreedharan, horms,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1060 bytes --]
On Wed, Sep 23, 2026 at 2:07 PM Joe Damato <joe@dama.to> wrote:
> @@ -7798,6 +7802,19 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
> bp->grp_info[i].cp_fw_ring_id = INVALID_HW_RING_ID;
> }
> }
> +
> + if (!stuck)
> + return 0;
> +
> + netdev_err(bp->dev, "Firmware did not free %d ring(s)\n", stuck);
> + return -EIO;
> +}
> +
> +static void bnxt_stop_dma(struct bnxt *bp)
> +{
> + netdev_err(bp->dev,
> + "Disabling DMA before releasing ring memory, a firmware reset is required\n");
> + pci_clear_master(bp->pdev);
> }
>
Thanks for the patches. The general scheme to more properly handle
RING_FREE timeout to prevent possible memory corruption is correct.
However, the corrective action here feels incomplete. We should at
least set some bp->state flags so that at the next open, we would know
that something was wrong and could take further actions (e.g. FLR,
etc) to try to bring it back.
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5469 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC net v3 3/3] bnxt_en: stop DMA before releasing rings the firmware did not free
2026-09-24 6:26 ` Michael Chan
@ 2026-09-24 17:41 ` Joe Damato
2026-09-24 19:47 ` Michael Chan
0 siblings, 1 reply; 7+ messages in thread
From: Joe Damato @ 2026-09-24 17:41 UTC (permalink / raw)
To: Michael Chan
Cc: netdev, Pavan Chebbi, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Prashant Sreedharan, horms,
linux-kernel
On Wed, Sep 23, 2026 at 11:26:47PM -0700, Michael Chan wrote:
> On Wed, Sep 23, 2026 at 2:07 PM Joe Damato <joe@dama.to> wrote:
>
> > @@ -7798,6 +7802,19 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
> > bp->grp_info[i].cp_fw_ring_id = INVALID_HW_RING_ID;
> > }
> > }
> > +
> > + if (!stuck)
> > + return 0;
> > +
> > + netdev_err(bp->dev, "Firmware did not free %d ring(s)\n", stuck);
> > + return -EIO;
> > +}
> > +
> > +static void bnxt_stop_dma(struct bnxt *bp)
> > +{
> > + netdev_err(bp->dev,
> > + "Disabling DMA before releasing ring memory, a firmware reset is required\n");
> > + pci_clear_master(bp->pdev);
> > }
> >
> Thanks for the patches. The general scheme to more properly handle
> RING_FREE timeout to prevent possible memory corruption is correct.
> However, the corrective action here feels incomplete. We should at
> least set some bp->state flags so that at the next open, we would know
> that something was wrong and could take further actions (e.g. FLR,
> etc) to try to bring it back.
Thanks for the review. That makes sense. Were you thinking of trying to bring
the device back up automatically or requiring user intervention?
The automatic path is probably somewhat tricky, it might look something like
(psuedo code):
#define BNXT_STATE_DMA_STOPPED 10
/* bnxt_stop_dma */
set_bit(BNXT_STATE_DMA_STOPPED, &bp->state);
pci_clear_master(bp->pdev);
/* bnxt_open, bnxt_open_nic, and probably bnxt_half_open_nic */
if (test_bit(BNXT_STATE_DMA_STOPPED, ...
bnxt_recover_stopped_dma(...)
/* pseudo code */
bnxt_recover_stopped_dma(...) {
pcie_flr();
pci_set_master();
bnxt_fw_init_one();
clear_bit(BNXT_STATE_DMA_STOPPED, ...
}
That's just a basic outline; I suspect the details will be much trickier and
would probably take a few revisions to get right.
Instead, if you are OK with leaving the device disabled until a user rebinds
it, then I'd define a new bit (BNXT_STATE_DMA_STOPPED), set it in
bnxt_stop_dma, and then return ENODEV from the open paths. Simpler, but
requires manual intervention when this occurs.
I am guessing you mean the former, but wanted to check before I started to try
to write that code.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC net v3 3/3] bnxt_en: stop DMA before releasing rings the firmware did not free
2026-09-24 17:41 ` Joe Damato
@ 2026-09-24 19:47 ` Michael Chan
0 siblings, 0 replies; 7+ messages in thread
From: Michael Chan @ 2026-09-24 19:47 UTC (permalink / raw)
To: Joe Damato, Michael Chan, netdev, Pavan Chebbi, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Prashant Sreedharan, horms, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 426 bytes --]
On Thu, Sep 24, 2026 at 10:41 AM Joe Damato <joe@dama.to> wrote:
> Instead, if you are OK with leaving the device disabled until a user rebinds
> it, then I'd define a new bit (BNXT_STATE_DMA_STOPPED), set it in
> bnxt_stop_dma, and then return ENODEV from the open paths. Simpler, but
> requires manual intervention when this occurs.
>
I think this is fine as a first step. We can improve on it later. Thanks.
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5469 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-24 19:47 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-23 21:07 [RFC net v3 0/3] bnxt_en: Make RING FREE more robust Joe Damato
2026-09-23 21:07 ` [RFC net v3 1/3] bnxt_en: return the RING_FREE status to callers Joe Damato
2026-09-23 21:07 ` [RFC net v3 2/3] bnxt_en: check HWRM response if completion never arrives Joe Damato
2026-09-23 21:07 ` [RFC net v3 3/3] bnxt_en: stop DMA before releasing rings the firmware did not free Joe Damato
2026-09-24 6:26 ` Michael Chan
2026-09-24 17:41 ` Joe Damato
2026-09-24 19:47 ` Michael Chan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®