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 Signed-off-by: Mark Bloch --- .../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