[PATCH net-next V2 3/7] net/mlx5: Clear FW reset-in-progress bit before reload

From: Mark Bloch

Date: Wed Jun 03 2026 - 15:39:51 EST


mlx5 sets MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS when acknowledging a sync
reset request. This bit blocks devlink reload and other devlink operations
while the firmware reset is running, but it was kept set until after the
driver reload finished.

Clear the reset-in-progress bit once the reset unload flow is done and PCI
access is back, before reloading the device. For a reset initiated through
devlink, clear it before completing the reload waiter. For a reset reported
through an asynchronous firmware event, keep the unload flow outside
devl_lock, then take devl_lock before clearing the bit and reloading
through the devl-locked load helper.

Reviewed-by: Shay Drori <shayd@xxxxxxxxxx>
Reviewed-by: Moshe Shemesh <moshe@xxxxxxxxxx>
Signed-off-by: Mark Bloch <mbloch@xxxxxxxxxx>
---
.../ethernet/mellanox/mlx5/core/fw_reset.c | 28 +++++++++++--------
1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
index 07440c58713a..7283e5b49eed 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
@@ -238,24 +238,30 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
{
struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
struct devlink *devlink = priv_to_devlink(dev);
+ int err;

/* if this is the driver that initiated the fw reset, devlink completed the reload */
if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
+ clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS,
+ &fw_reset->reset_flags);
complete(&fw_reset->done);
- } else {
- mlx5_sync_reset_unload_flow(dev, false);
- if (mlx5_health_wait_pci_up(dev))
- mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
- else
- mlx5_load_one(dev, true);
- devl_lock(devlink);
- devlink_remote_reload_actions_performed(devlink, 0,
- BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
- BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
- devl_unlock(devlink);
+ return;
}

+ mlx5_sync_reset_unload_flow(dev, false);
+ err = mlx5_health_wait_pci_up(dev);
+
+ devl_lock(devlink);
clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+ if (err)
+ mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+ else
+ mlx5_load_one_devl_locked(dev, true);
+
+ devlink_remote_reload_actions_performed(devlink, 0,
+ BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
+ BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
+ devl_unlock(devlink);
}

static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev)
--
2.34.1