[PATCH net-next V2 4/7] net/mlx5: Register devlink after device init
From: Mark Bloch
Date: Wed Jun 03 2026 - 15:34:32 EST
devl_register() makes the devlink instance visible to userspace. A later
patch also makes registration the point where devlink core may call
eswitch_mode_set() to apply a boot-time default eswitch mode.
Move mlx5 devlink registration after mlx5 device initialization completes,
including the lightweight init path, so registration-time devlink
operations see initialized driver state.
Move devl_unregister() before the matching teardown paths, so unregister
notifications are emitted from devl_unregister() before mlx5 removes the
devlink objects.
Add a devl-locked uninit helper so failed nested devlink setup can unwind
the initialized device before the instance is registered.
Reviewed-by: Shay Drori <shayd@xxxxxxxxxx>
Signed-off-by: Mark Bloch <mbloch@xxxxxxxxxx>
---
.../net/ethernet/mellanox/mlx5/core/main.c | 34 ++++++++++++++-----
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 0c6e4efe38c8..ab3d3ff10f1a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -1455,31 +1455,40 @@ int mlx5_init_one_devl_locked(struct mlx5_core_dev *dev)
return err;
}
+static void mlx5_uninit_one_devl_locked(struct mlx5_core_dev *dev);
+
int mlx5_init_one(struct mlx5_core_dev *dev)
{
struct devlink *devlink = priv_to_devlink(dev);
int err;
devl_lock(devlink);
+ err = mlx5_init_one_devl_locked(dev);
+ if (err)
+ goto unlock;
+
if (dev->shd) {
err = devl_nested_devlink_set(dev->shd, devlink);
if (err)
- goto unlock;
+ goto err_uninit;
}
+
devl_register(devlink);
- err = mlx5_init_one_devl_locked(dev);
- if (err)
- devl_unregister(devlink);
+ devl_unlock(devlink);
+ return 0;
+
+err_uninit:
+ mlx5_uninit_one_devl_locked(dev);
unlock:
devl_unlock(devlink);
return err;
}
-void mlx5_uninit_one(struct mlx5_core_dev *dev)
+static void mlx5_uninit_one_devl_locked(struct mlx5_core_dev *dev)
{
struct devlink *devlink = priv_to_devlink(dev);
- devl_lock(devlink);
+ devl_assert_locked(devlink);
mutex_lock(&dev->intf_state_mutex);
mlx5_hwmon_dev_unregister(dev);
@@ -1501,7 +1510,15 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev)
mlx5_function_teardown(dev, true);
out:
mutex_unlock(&dev->intf_state_mutex);
+}
+
+void mlx5_uninit_one(struct mlx5_core_dev *dev)
+{
+ struct devlink *devlink = priv_to_devlink(dev);
+
+ devl_lock(devlink);
devl_unregister(devlink);
+ mlx5_uninit_one_devl_locked(dev);
devl_unlock(devlink);
}
@@ -1635,7 +1652,6 @@ int mlx5_init_one_light(struct mlx5_core_dev *dev)
int err;
devl_lock(devlink);
- devl_register(devlink);
dev->state = MLX5_DEVICE_STATE_UP;
err = mlx5_function_enable(dev, true, mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT));
if (err) {
@@ -1655,6 +1671,7 @@ int mlx5_init_one_light(struct mlx5_core_dev *dev)
goto query_hca_caps_err;
}
+ devl_register(devlink);
devl_unlock(devlink);
return 0;
@@ -1662,7 +1679,6 @@ int mlx5_init_one_light(struct mlx5_core_dev *dev)
mlx5_function_disable(dev, true);
out:
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
- devl_unregister(devlink);
devl_unlock(devlink);
return err;
}
@@ -1672,8 +1688,8 @@ void mlx5_uninit_one_light(struct mlx5_core_dev *dev)
struct devlink *devlink = priv_to_devlink(dev);
devl_lock(devlink);
- mlx5_devlink_params_unregister(priv_to_devlink(dev));
devl_unregister(devlink);
+ mlx5_devlink_params_unregister(priv_to_devlink(dev));
devl_unlock(devlink);
if (dev->state != MLX5_DEVICE_STATE_UP)
return;
--
2.34.1