Commit 13719a5b authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'take-devlink-lock-on-mlx4-and-mlx5-callbacks'

Moshe Shemesh says:

====================
Take devlink lock on mlx4 and mlx5 callbacks

Prepare mlx4 and mlx5 drivers to have all devlink callbacks called with
devlink instance locked. Change mlx4 driver to use devl_ API where
needed to have devlink reload callbacks locked. Change mlx5 driver to
use devl_ API where needed to have devlink reload and devlink health
callbacks locked.

As mlx5 is the only driver which needed changes to enable calling health
callbacks with devlink instance locked, this patchset also removes
DEVLINK_NL_FLAG_NO_LOCK flag from devlink health callbacks.

This patchset will be followed by a patchset that will remove
DEVLINK_NL_FLAG_NO_LOCK flag from devlink and will remove devlink_mutex.
====================

Link: https://lore.kernel.org/r/1659023630-32006-1-git-send-email-moshe@nvidia.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1515a1b8 c90005b5
...@@ -204,9 +204,13 @@ void mlx4_enter_error_state(struct mlx4_dev_persistent *persist) ...@@ -204,9 +204,13 @@ void mlx4_enter_error_state(struct mlx4_dev_persistent *persist)
static void mlx4_handle_error_state(struct mlx4_dev_persistent *persist) static void mlx4_handle_error_state(struct mlx4_dev_persistent *persist)
{ {
struct mlx4_dev *dev = persist->dev;
struct devlink *devlink;
int err = 0; int err = 0;
mlx4_enter_error_state(persist); mlx4_enter_error_state(persist);
devlink = priv_to_devlink(mlx4_priv(dev));
devl_lock(devlink);
mutex_lock(&persist->interface_state_mutex); mutex_lock(&persist->interface_state_mutex);
if (persist->interface_state & MLX4_INTERFACE_STATE_UP && if (persist->interface_state & MLX4_INTERFACE_STATE_UP &&
!(persist->interface_state & MLX4_INTERFACE_STATE_DELETION)) { !(persist->interface_state & MLX4_INTERFACE_STATE_DELETION)) {
...@@ -215,6 +219,7 @@ static void mlx4_handle_error_state(struct mlx4_dev_persistent *persist) ...@@ -215,6 +219,7 @@ static void mlx4_handle_error_state(struct mlx4_dev_persistent *persist)
err); err);
} }
mutex_unlock(&persist->interface_state_mutex); mutex_unlock(&persist->interface_state_mutex);
devl_unlock(devlink);
} }
static void dump_err_buf(struct mlx4_dev *dev) static void dump_err_buf(struct mlx4_dev *dev)
......
...@@ -226,10 +226,10 @@ int mlx4_crdump_init(struct mlx4_dev *dev) ...@@ -226,10 +226,10 @@ int mlx4_crdump_init(struct mlx4_dev *dev)
/* Create cr-space region */ /* Create cr-space region */
crdump->region_crspace = crdump->region_crspace =
devlink_region_create(devlink, devl_region_create(devlink,
&region_cr_space_ops, &region_cr_space_ops,
MAX_NUM_OF_DUMPS_TO_STORE, MAX_NUM_OF_DUMPS_TO_STORE,
pci_resource_len(pdev, 0)); pci_resource_len(pdev, 0));
if (IS_ERR(crdump->region_crspace)) if (IS_ERR(crdump->region_crspace))
mlx4_warn(dev, "crdump: create devlink region %s err %ld\n", mlx4_warn(dev, "crdump: create devlink region %s err %ld\n",
region_cr_space_str, region_cr_space_str,
...@@ -237,10 +237,10 @@ int mlx4_crdump_init(struct mlx4_dev *dev) ...@@ -237,10 +237,10 @@ int mlx4_crdump_init(struct mlx4_dev *dev)
/* Create fw-health region */ /* Create fw-health region */
crdump->region_fw_health = crdump->region_fw_health =
devlink_region_create(devlink, devl_region_create(devlink,
&region_fw_health_ops, &region_fw_health_ops,
MAX_NUM_OF_DUMPS_TO_STORE, MAX_NUM_OF_DUMPS_TO_STORE,
HEALTH_BUFFER_SIZE); HEALTH_BUFFER_SIZE);
if (IS_ERR(crdump->region_fw_health)) if (IS_ERR(crdump->region_fw_health))
mlx4_warn(dev, "crdump: create devlink region %s err %ld\n", mlx4_warn(dev, "crdump: create devlink region %s err %ld\n",
region_fw_health_str, region_fw_health_str,
...@@ -253,6 +253,6 @@ void mlx4_crdump_end(struct mlx4_dev *dev) ...@@ -253,6 +253,6 @@ void mlx4_crdump_end(struct mlx4_dev *dev)
{ {
struct mlx4_fw_crdump *crdump = &dev->persist->crdump; struct mlx4_fw_crdump *crdump = &dev->persist->crdump;
devlink_region_destroy(crdump->region_fw_health); devl_region_destroy(crdump->region_fw_health);
devlink_region_destroy(crdump->region_crspace); devl_region_destroy(crdump->region_crspace);
} }
...@@ -3033,7 +3033,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) ...@@ -3033,7 +3033,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
int err; int err;
err = devlink_port_register(devlink, &info->devlink_port, port); err = devl_port_register(devlink, &info->devlink_port, port);
if (err) if (err)
return err; return err;
...@@ -3071,7 +3071,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) ...@@ -3071,7 +3071,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
err = device_create_file(&dev->persist->pdev->dev, &info->port_attr); err = device_create_file(&dev->persist->pdev->dev, &info->port_attr);
if (err) { if (err) {
mlx4_err(dev, "Failed to create file for port %d\n", port); mlx4_err(dev, "Failed to create file for port %d\n", port);
devlink_port_unregister(&info->devlink_port); devl_port_unregister(&info->devlink_port);
info->port = -1; info->port = -1;
return err; return err;
} }
...@@ -3093,7 +3093,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) ...@@ -3093,7 +3093,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
mlx4_err(dev, "Failed to create mtu file for port %d\n", port); mlx4_err(dev, "Failed to create mtu file for port %d\n", port);
device_remove_file(&info->dev->persist->pdev->dev, device_remove_file(&info->dev->persist->pdev->dev,
&info->port_attr); &info->port_attr);
devlink_port_unregister(&info->devlink_port); devl_port_unregister(&info->devlink_port);
info->port = -1; info->port = -1;
return err; return err;
} }
...@@ -3109,7 +3109,7 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info) ...@@ -3109,7 +3109,7 @@ static void mlx4_cleanup_port_info(struct mlx4_port_info *info)
device_remove_file(&info->dev->persist->pdev->dev, &info->port_attr); device_remove_file(&info->dev->persist->pdev->dev, &info->port_attr);
device_remove_file(&info->dev->persist->pdev->dev, device_remove_file(&info->dev->persist->pdev->dev,
&info->port_mtu_attr); &info->port_mtu_attr);
devlink_port_unregister(&info->devlink_port); devl_port_unregister(&info->devlink_port);
#ifdef CONFIG_RFS_ACCEL #ifdef CONFIG_RFS_ACCEL
free_irq_cpu_rmap(info->rmap); free_irq_cpu_rmap(info->rmap);
...@@ -3333,6 +3333,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, ...@@ -3333,6 +3333,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
int total_vfs, int *nvfs, struct mlx4_priv *priv, int total_vfs, int *nvfs, struct mlx4_priv *priv,
int reset_flow) int reset_flow)
{ {
struct devlink *devlink = priv_to_devlink(priv);
struct mlx4_dev *dev; struct mlx4_dev *dev;
unsigned sum = 0; unsigned sum = 0;
int err; int err;
...@@ -3341,6 +3342,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, ...@@ -3341,6 +3342,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
struct mlx4_dev_cap *dev_cap = NULL; struct mlx4_dev_cap *dev_cap = NULL;
int existing_vfs = 0; int existing_vfs = 0;
devl_assert_locked(devlink);
dev = &priv->dev; dev = &priv->dev;
INIT_LIST_HEAD(&priv->ctx_list); INIT_LIST_HEAD(&priv->ctx_list);
...@@ -3956,9 +3958,11 @@ static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change, ...@@ -3956,9 +3958,11 @@ static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change,
NL_SET_ERR_MSG_MOD(extack, "Namespace change is not supported"); NL_SET_ERR_MSG_MOD(extack, "Namespace change is not supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
devl_lock(devlink);
if (persist->num_vfs) if (persist->num_vfs)
mlx4_warn(persist->dev, "Reload performed on PF, will cause reset on operating Virtual Functions\n"); mlx4_warn(persist->dev, "Reload performed on PF, will cause reset on operating Virtual Functions\n");
mlx4_restart_one_down(persist->pdev); mlx4_restart_one_down(persist->pdev);
devl_unlock(devlink);
return 0; return 0;
} }
...@@ -3971,8 +3975,10 @@ static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a ...@@ -3971,8 +3975,10 @@ static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a
struct mlx4_dev_persistent *persist = dev->persist; struct mlx4_dev_persistent *persist = dev->persist;
int err; int err;
devl_lock(devlink);
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
err = mlx4_restart_one_up(persist->pdev, true, devlink); err = mlx4_restart_one_up(persist->pdev, true, devlink);
devl_unlock(devlink);
if (err) if (err)
mlx4_err(persist->dev, "mlx4_restart_one_up failed, ret=%d\n", mlx4_err(persist->dev, "mlx4_restart_one_up failed, ret=%d\n",
err); err);
...@@ -3999,6 +4005,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -3999,6 +4005,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
devlink = devlink_alloc(&mlx4_devlink_ops, sizeof(*priv), &pdev->dev); devlink = devlink_alloc(&mlx4_devlink_ops, sizeof(*priv), &pdev->dev);
if (!devlink) if (!devlink)
return -ENOMEM; return -ENOMEM;
devl_lock(devlink);
priv = devlink_priv(devlink); priv = devlink_priv(devlink);
dev = &priv->dev; dev = &priv->dev;
...@@ -4026,6 +4033,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -4026,6 +4033,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_save_state(pdev); pci_save_state(pdev);
devlink_set_features(devlink, DEVLINK_F_RELOAD); devlink_set_features(devlink, DEVLINK_F_RELOAD);
devl_unlock(devlink);
devlink_register(devlink); devlink_register(devlink);
return 0; return 0;
...@@ -4035,6 +4043,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -4035,6 +4043,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
err_devlink_unregister: err_devlink_unregister:
kfree(dev->persist); kfree(dev->persist);
err_devlink_free: err_devlink_free:
devl_unlock(devlink);
devlink_free(devlink); devlink_free(devlink);
return ret; return ret;
} }
...@@ -4056,8 +4065,11 @@ static void mlx4_unload_one(struct pci_dev *pdev) ...@@ -4056,8 +4065,11 @@ static void mlx4_unload_one(struct pci_dev *pdev)
struct mlx4_dev *dev = persist->dev; struct mlx4_dev *dev = persist->dev;
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
int pci_dev_data; int pci_dev_data;
struct devlink *devlink;
int p, i; int p, i;
devlink = priv_to_devlink(priv);
devl_assert_locked(devlink);
if (priv->removed) if (priv->removed)
return; return;
...@@ -4137,6 +4149,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) ...@@ -4137,6 +4149,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
devlink_unregister(devlink); devlink_unregister(devlink);
devl_lock(devlink);
if (mlx4_is_slave(dev)) if (mlx4_is_slave(dev))
persist->interface_state |= MLX4_INTERFACE_STATE_NOWAIT; persist->interface_state |= MLX4_INTERFACE_STATE_NOWAIT;
...@@ -4172,6 +4185,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) ...@@ -4172,6 +4185,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
devlink_params_unregister(devlink, mlx4_devlink_params, devlink_params_unregister(devlink, mlx4_devlink_params,
ARRAY_SIZE(mlx4_devlink_params)); ARRAY_SIZE(mlx4_devlink_params));
kfree(dev->persist); kfree(dev->persist);
devl_unlock(devlink);
devlink_free(devlink); devlink_free(devlink);
} }
...@@ -4292,15 +4306,20 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev, ...@@ -4292,15 +4306,20 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
pci_channel_state_t state) pci_channel_state_t state)
{ {
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
struct mlx4_dev *dev = persist->dev;
struct devlink *devlink;
mlx4_err(persist->dev, "mlx4_pci_err_detected was called\n"); mlx4_err(persist->dev, "mlx4_pci_err_detected was called\n");
mlx4_enter_error_state(persist); mlx4_enter_error_state(persist);
devlink = priv_to_devlink(mlx4_priv(dev));
devl_lock(devlink);
mutex_lock(&persist->interface_state_mutex); mutex_lock(&persist->interface_state_mutex);
if (persist->interface_state & MLX4_INTERFACE_STATE_UP) if (persist->interface_state & MLX4_INTERFACE_STATE_UP)
mlx4_unload_one(pdev); mlx4_unload_one(pdev);
mutex_unlock(&persist->interface_state_mutex); mutex_unlock(&persist->interface_state_mutex);
devl_unlock(devlink);
if (state == pci_channel_io_perm_failure) if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT; return PCI_ERS_RESULT_DISCONNECT;
...@@ -4333,6 +4352,7 @@ static void mlx4_pci_resume(struct pci_dev *pdev) ...@@ -4333,6 +4352,7 @@ static void mlx4_pci_resume(struct pci_dev *pdev)
struct mlx4_dev *dev = persist->dev; struct mlx4_dev *dev = persist->dev;
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0}; int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0};
struct devlink *devlink;
int total_vfs; int total_vfs;
int err; int err;
...@@ -4340,6 +4360,8 @@ static void mlx4_pci_resume(struct pci_dev *pdev) ...@@ -4340,6 +4360,8 @@ static void mlx4_pci_resume(struct pci_dev *pdev)
total_vfs = dev->persist->num_vfs; total_vfs = dev->persist->num_vfs;
memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs)); memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs));
devlink = priv_to_devlink(priv);
devl_lock(devlink);
mutex_lock(&persist->interface_state_mutex); mutex_lock(&persist->interface_state_mutex);
if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) { if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) {
err = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs, err = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs,
...@@ -4358,19 +4380,23 @@ static void mlx4_pci_resume(struct pci_dev *pdev) ...@@ -4358,19 +4380,23 @@ static void mlx4_pci_resume(struct pci_dev *pdev)
} }
end: end:
mutex_unlock(&persist->interface_state_mutex); mutex_unlock(&persist->interface_state_mutex);
devl_unlock(devlink);
} }
static void mlx4_shutdown(struct pci_dev *pdev) static void mlx4_shutdown(struct pci_dev *pdev)
{ {
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
struct mlx4_dev *dev = persist->dev; struct mlx4_dev *dev = persist->dev;
struct devlink *devlink;
mlx4_info(persist->dev, "mlx4_shutdown was called\n"); mlx4_info(persist->dev, "mlx4_shutdown was called\n");
devlink = priv_to_devlink(mlx4_priv(dev));
devl_lock(devlink);
mutex_lock(&persist->interface_state_mutex); mutex_lock(&persist->interface_state_mutex);
if (persist->interface_state & MLX4_INTERFACE_STATE_UP) if (persist->interface_state & MLX4_INTERFACE_STATE_UP)
mlx4_unload_one(pdev); mlx4_unload_one(pdev);
mutex_unlock(&persist->interface_state_mutex); mutex_unlock(&persist->interface_state_mutex);
devl_unlock(devlink);
mlx4_pci_disable_device(dev); mlx4_pci_disable_device(dev);
} }
...@@ -4385,12 +4411,16 @@ static int __maybe_unused mlx4_suspend(struct device *dev_d) ...@@ -4385,12 +4411,16 @@ static int __maybe_unused mlx4_suspend(struct device *dev_d)
struct pci_dev *pdev = to_pci_dev(dev_d); struct pci_dev *pdev = to_pci_dev(dev_d);
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
struct mlx4_dev *dev = persist->dev; struct mlx4_dev *dev = persist->dev;
struct devlink *devlink;
mlx4_err(dev, "suspend was called\n"); mlx4_err(dev, "suspend was called\n");
devlink = priv_to_devlink(mlx4_priv(dev));
devl_lock(devlink);
mutex_lock(&persist->interface_state_mutex); mutex_lock(&persist->interface_state_mutex);
if (persist->interface_state & MLX4_INTERFACE_STATE_UP) if (persist->interface_state & MLX4_INTERFACE_STATE_UP)
mlx4_unload_one(pdev); mlx4_unload_one(pdev);
mutex_unlock(&persist->interface_state_mutex); mutex_unlock(&persist->interface_state_mutex);
devl_unlock(devlink);
return 0; return 0;
} }
...@@ -4402,6 +4432,7 @@ static int __maybe_unused mlx4_resume(struct device *dev_d) ...@@ -4402,6 +4432,7 @@ static int __maybe_unused mlx4_resume(struct device *dev_d)
struct mlx4_dev *dev = persist->dev; struct mlx4_dev *dev = persist->dev;
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0}; int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0};
struct devlink *devlink;
int total_vfs; int total_vfs;
int ret = 0; int ret = 0;
...@@ -4409,6 +4440,8 @@ static int __maybe_unused mlx4_resume(struct device *dev_d) ...@@ -4409,6 +4440,8 @@ static int __maybe_unused mlx4_resume(struct device *dev_d)
total_vfs = dev->persist->num_vfs; total_vfs = dev->persist->num_vfs;
memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs)); memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs));
devlink = priv_to_devlink(priv);
devl_lock(devlink);
mutex_lock(&persist->interface_state_mutex); mutex_lock(&persist->interface_state_mutex);
if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) { if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) {
ret = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, ret = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs,
...@@ -4422,6 +4455,7 @@ static int __maybe_unused mlx4_resume(struct device *dev_d) ...@@ -4422,6 +4455,7 @@ static int __maybe_unused mlx4_resume(struct device *dev_d)
} }
} }
mutex_unlock(&persist->interface_state_mutex); mutex_unlock(&persist->interface_state_mutex);
devl_unlock(devlink);
return ret; return ret;
} }
......
...@@ -335,13 +335,12 @@ static void del_adev(struct auxiliary_device *adev) ...@@ -335,13 +335,12 @@ static void del_adev(struct auxiliary_device *adev)
int mlx5_attach_device(struct mlx5_core_dev *dev) int mlx5_attach_device(struct mlx5_core_dev *dev)
{ {
struct devlink *devlink = priv_to_devlink(dev);
struct mlx5_priv *priv = &dev->priv; struct mlx5_priv *priv = &dev->priv;
struct auxiliary_device *adev; struct auxiliary_device *adev;
struct auxiliary_driver *adrv; struct auxiliary_driver *adrv;
int ret = 0, i; int ret = 0, i;
devl_lock(devlink); devl_assert_locked(priv_to_devlink(dev));
mutex_lock(&mlx5_intf_mutex); mutex_lock(&mlx5_intf_mutex);
priv->flags &= ~MLX5_PRIV_FLAGS_DETACH; priv->flags &= ~MLX5_PRIV_FLAGS_DETACH;
priv->flags |= MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW; priv->flags |= MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW;
...@@ -394,20 +393,18 @@ int mlx5_attach_device(struct mlx5_core_dev *dev) ...@@ -394,20 +393,18 @@ int mlx5_attach_device(struct mlx5_core_dev *dev)
} }
priv->flags &= ~MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW; priv->flags &= ~MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW;
mutex_unlock(&mlx5_intf_mutex); mutex_unlock(&mlx5_intf_mutex);
devl_unlock(devlink);
return ret; return ret;
} }
void mlx5_detach_device(struct mlx5_core_dev *dev) void mlx5_detach_device(struct mlx5_core_dev *dev)
{ {
struct devlink *devlink = priv_to_devlink(dev);
struct mlx5_priv *priv = &dev->priv; struct mlx5_priv *priv = &dev->priv;
struct auxiliary_device *adev; struct auxiliary_device *adev;
struct auxiliary_driver *adrv; struct auxiliary_driver *adrv;
pm_message_t pm = {}; pm_message_t pm = {};
int i; int i;
devl_lock(devlink); devl_assert_locked(priv_to_devlink(dev));
mutex_lock(&mlx5_intf_mutex); mutex_lock(&mlx5_intf_mutex);
priv->flags |= MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW; priv->flags |= MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW;
for (i = ARRAY_SIZE(mlx5_adev_devices) - 1; i >= 0; i--) { for (i = ARRAY_SIZE(mlx5_adev_devices) - 1; i >= 0; i--) {
...@@ -441,21 +438,17 @@ void mlx5_detach_device(struct mlx5_core_dev *dev) ...@@ -441,21 +438,17 @@ void mlx5_detach_device(struct mlx5_core_dev *dev)
priv->flags &= ~MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW; priv->flags &= ~MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW;
priv->flags |= MLX5_PRIV_FLAGS_DETACH; priv->flags |= MLX5_PRIV_FLAGS_DETACH;
mutex_unlock(&mlx5_intf_mutex); mutex_unlock(&mlx5_intf_mutex);
devl_unlock(devlink);
} }
int mlx5_register_device(struct mlx5_core_dev *dev) int mlx5_register_device(struct mlx5_core_dev *dev)
{ {
struct devlink *devlink;
int ret; int ret;
devlink = priv_to_devlink(dev); devl_assert_locked(priv_to_devlink(dev));
devl_lock(devlink);
mutex_lock(&mlx5_intf_mutex); mutex_lock(&mlx5_intf_mutex);
dev->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV; dev->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV;
ret = mlx5_rescan_drivers_locked(dev); ret = mlx5_rescan_drivers_locked(dev);
mutex_unlock(&mlx5_intf_mutex); mutex_unlock(&mlx5_intf_mutex);
devl_unlock(devlink);
if (ret) if (ret)
mlx5_unregister_device(dev); mlx5_unregister_device(dev);
...@@ -464,15 +457,11 @@ int mlx5_register_device(struct mlx5_core_dev *dev) ...@@ -464,15 +457,11 @@ int mlx5_register_device(struct mlx5_core_dev *dev)
void mlx5_unregister_device(struct mlx5_core_dev *dev) void mlx5_unregister_device(struct mlx5_core_dev *dev)
{ {
struct devlink *devlink; devl_assert_locked(priv_to_devlink(dev));
devlink = priv_to_devlink(dev);
devl_lock(devlink);
mutex_lock(&mlx5_intf_mutex); mutex_lock(&mlx5_intf_mutex);
dev->priv.flags = MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV; dev->priv.flags = MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV;
mlx5_rescan_drivers_locked(dev); mlx5_rescan_drivers_locked(dev);
mutex_unlock(&mlx5_intf_mutex); mutex_unlock(&mlx5_intf_mutex);
devl_unlock(devlink);
} }
static int add_drivers(struct mlx5_core_dev *dev) static int add_drivers(struct mlx5_core_dev *dev)
......
...@@ -104,7 +104,16 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli ...@@ -104,7 +104,16 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
if (err) if (err)
return err; return err;
return mlx5_fw_reset_wait_reset_done(dev); err = mlx5_fw_reset_wait_reset_done(dev);
if (err)
return err;
mlx5_unload_one_devl_locked(dev);
err = mlx5_health_wait_pci_up(dev);
if (err)
NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
return err;
} }
static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink, static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink,
...@@ -134,6 +143,7 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change, ...@@ -134,6 +143,7 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
struct mlx5_core_dev *dev = devlink_priv(devlink); struct mlx5_core_dev *dev = devlink_priv(devlink);
struct pci_dev *pdev = dev->pdev; struct pci_dev *pdev = dev->pdev;
bool sf_dev_allocated; bool sf_dev_allocated;
int ret = 0;
sf_dev_allocated = mlx5_sf_dev_allocated(dev); sf_dev_allocated = mlx5_sf_dev_allocated(dev);
if (sf_dev_allocated) { if (sf_dev_allocated) {
...@@ -154,19 +164,25 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change, ...@@ -154,19 +164,25 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
NL_SET_ERR_MSG_MOD(extack, "reload while VFs are present is unfavorable"); NL_SET_ERR_MSG_MOD(extack, "reload while VFs are present is unfavorable");
} }
devl_lock(devlink);
switch (action) { switch (action) {
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
mlx5_unload_one(dev); mlx5_unload_one_devl_locked(dev);
return 0; break;
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
return mlx5_devlink_trigger_fw_live_patch(devlink, extack); ret = mlx5_devlink_trigger_fw_live_patch(devlink, extack);
return mlx5_devlink_reload_fw_activate(devlink, extack); else
ret = mlx5_devlink_reload_fw_activate(devlink, extack);
break;
default: default:
/* Unsupported action should not get to this function */ /* Unsupported action should not get to this function */
WARN_ON(1); WARN_ON(1);
return -EOPNOTSUPP; ret = -EOPNOTSUPP;
} }
devl_unlock(devlink);
return ret;
} }
static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action, static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
...@@ -174,24 +190,29 @@ static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a ...@@ -174,24 +190,29 @@ static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlx5_core_dev *dev = devlink_priv(devlink); struct mlx5_core_dev *dev = devlink_priv(devlink);
int ret = 0;
devl_lock(devlink);
*actions_performed = BIT(action); *actions_performed = BIT(action);
switch (action) { switch (action) {
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
return mlx5_load_one(dev, false); ret = mlx5_load_one_devl_locked(dev, false);
break;
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
break; break;
/* On fw_activate action, also driver is reloaded and reinit performed */ /* On fw_activate action, also driver is reloaded and reinit performed */
*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
return mlx5_load_one(dev, false); ret = mlx5_load_one_devl_locked(dev, false);
break;
default: default:
/* Unsupported action should not get to this function */ /* Unsupported action should not get to this function */
WARN_ON(1); WARN_ON(1);
return -EOPNOTSUPP; ret = -EOPNOTSUPP;
} }
return 0; devl_unlock(devlink);
return ret;
} }
static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id) static struct mlx5_devlink_trap *mlx5_find_trap_by_id(struct mlx5_core_dev *dev, int trap_id)
...@@ -828,28 +849,28 @@ static int mlx5_devlink_traps_register(struct devlink *devlink) ...@@ -828,28 +849,28 @@ static int mlx5_devlink_traps_register(struct devlink *devlink)
struct mlx5_core_dev *core_dev = devlink_priv(devlink); struct mlx5_core_dev *core_dev = devlink_priv(devlink);
int err; int err;
err = devlink_trap_groups_register(devlink, mlx5_trap_groups_arr, err = devl_trap_groups_register(devlink, mlx5_trap_groups_arr,
ARRAY_SIZE(mlx5_trap_groups_arr)); ARRAY_SIZE(mlx5_trap_groups_arr));
if (err) if (err)
return err; return err;
err = devlink_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr), err = devl_traps_register(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr),
&core_dev->priv); &core_dev->priv);
if (err) if (err)
goto err_trap_group; goto err_trap_group;
return 0; return 0;
err_trap_group: err_trap_group:
devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr, devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
ARRAY_SIZE(mlx5_trap_groups_arr)); ARRAY_SIZE(mlx5_trap_groups_arr));
return err; return err;
} }
static void mlx5_devlink_traps_unregister(struct devlink *devlink) static void mlx5_devlink_traps_unregister(struct devlink *devlink)
{ {
devlink_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr)); devl_traps_unregister(devlink, mlx5_traps_arr, ARRAY_SIZE(mlx5_traps_arr));
devlink_trap_groups_unregister(devlink, mlx5_trap_groups_arr, devl_trap_groups_unregister(devlink, mlx5_trap_groups_arr,
ARRAY_SIZE(mlx5_trap_groups_arr)); ARRAY_SIZE(mlx5_trap_groups_arr));
} }
int mlx5_devlink_register(struct devlink *devlink) int mlx5_devlink_register(struct devlink *devlink)
......
...@@ -1300,20 +1300,19 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) ...@@ -1300,20 +1300,19 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs)
*/ */
int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
{ {
struct devlink *devlink;
bool toggle_lag; bool toggle_lag;
int ret; int ret;
if (!mlx5_esw_allowed(esw)) if (!mlx5_esw_allowed(esw))
return 0; return 0;
devl_assert_locked(priv_to_devlink(esw->dev));
toggle_lag = !mlx5_esw_is_fdb_created(esw); toggle_lag = !mlx5_esw_is_fdb_created(esw);
if (toggle_lag) if (toggle_lag)
mlx5_lag_disable_change(esw->dev); mlx5_lag_disable_change(esw->dev);
devlink = priv_to_devlink(esw->dev);
devl_lock(devlink);
down_write(&esw->mode_lock); down_write(&esw->mode_lock);
if (!mlx5_esw_is_fdb_created(esw)) { if (!mlx5_esw_is_fdb_created(esw)) {
ret = mlx5_eswitch_enable_locked(esw, num_vfs); ret = mlx5_eswitch_enable_locked(esw, num_vfs);
...@@ -1327,7 +1326,6 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) ...@@ -1327,7 +1326,6 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
esw->esw_funcs.num_vfs = num_vfs; esw->esw_funcs.num_vfs = num_vfs;
} }
up_write(&esw->mode_lock); up_write(&esw->mode_lock);
devl_unlock(devlink);
if (toggle_lag) if (toggle_lag)
mlx5_lag_enable_change(esw->dev); mlx5_lag_enable_change(esw->dev);
...@@ -1338,13 +1336,10 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) ...@@ -1338,13 +1336,10 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
/* When disabling sriov, free driver level resources. */ /* When disabling sriov, free driver level resources. */
void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf) void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf)
{ {
struct devlink *devlink;
if (!mlx5_esw_allowed(esw)) if (!mlx5_esw_allowed(esw))
return; return;
devlink = priv_to_devlink(esw->dev); devl_assert_locked(priv_to_devlink(esw->dev));
devl_lock(devlink);
down_write(&esw->mode_lock); down_write(&esw->mode_lock);
/* If driver is unloaded, this function is called twice by remove_one() /* If driver is unloaded, this function is called twice by remove_one()
* and mlx5_unload(). Prevent the second call. * and mlx5_unload(). Prevent the second call.
...@@ -1373,7 +1368,6 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf) ...@@ -1373,7 +1368,6 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf)
unlock: unlock:
up_write(&esw->mode_lock); up_write(&esw->mode_lock);
devl_unlock(devlink);
} }
/* Free resources for corresponding eswitch mode. It is called by devlink /* Free resources for corresponding eswitch mode. It is called by devlink
...@@ -1407,18 +1401,14 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw) ...@@ -1407,18 +1401,14 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw)
void mlx5_eswitch_disable(struct mlx5_eswitch *esw) void mlx5_eswitch_disable(struct mlx5_eswitch *esw)
{ {
struct devlink *devlink;
if (!mlx5_esw_allowed(esw)) if (!mlx5_esw_allowed(esw))
return; return;
devl_assert_locked(priv_to_devlink(esw->dev));
mlx5_lag_disable_change(esw->dev); mlx5_lag_disable_change(esw->dev);
devlink = priv_to_devlink(esw->dev);
devl_lock(devlink);
down_write(&esw->mode_lock); down_write(&esw->mode_lock);
mlx5_eswitch_disable_locked(esw); mlx5_eswitch_disable_locked(esw);
up_write(&esw->mode_lock); up_write(&esw->mode_lock);
devl_unlock(devlink);
mlx5_lag_enable_change(esw->dev); mlx5_lag_enable_change(esw->dev);
} }
......
...@@ -149,6 +149,9 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev) ...@@ -149,6 +149,9 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) { if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
complete(&fw_reset->done); complete(&fw_reset->done);
} else { } else {
mlx5_unload_one(dev);
if (mlx5_health_wait_pci_up(dev))
mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
mlx5_load_one(dev, false); mlx5_load_one(dev, false);
devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0, devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0,
BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
...@@ -183,15 +186,9 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work) ...@@ -183,15 +186,9 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work)
struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
reset_reload_work); reset_reload_work);
struct mlx5_core_dev *dev = fw_reset->dev; struct mlx5_core_dev *dev = fw_reset->dev;
int err;
mlx5_sync_reset_clear_reset_requested(dev, false); mlx5_sync_reset_clear_reset_requested(dev, false);
mlx5_enter_error_state(dev, true); mlx5_enter_error_state(dev, true);
mlx5_unload_one(dev);
err = mlx5_health_wait_pci_up(dev);
if (err)
mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
fw_reset->ret = err;
mlx5_fw_reset_complete_reload(dev); mlx5_fw_reset_complete_reload(dev);
} }
...@@ -395,7 +392,6 @@ static void mlx5_sync_reset_now_event(struct work_struct *work) ...@@ -395,7 +392,6 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
} }
mlx5_enter_error_state(dev, true); mlx5_enter_error_state(dev, true);
mlx5_unload_one(dev);
done: done:
fw_reset->ret = err; fw_reset->ret = err;
mlx5_fw_reset_complete_reload(dev); mlx5_fw_reset_complete_reload(dev);
......
...@@ -666,16 +666,20 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work) ...@@ -666,16 +666,20 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work)
struct mlx5_fw_reporter_ctx fw_reporter_ctx; struct mlx5_fw_reporter_ctx fw_reporter_ctx;
struct mlx5_core_health *health; struct mlx5_core_health *health;
struct mlx5_core_dev *dev; struct mlx5_core_dev *dev;
struct devlink *devlink;
struct mlx5_priv *priv; struct mlx5_priv *priv;
health = container_of(work, struct mlx5_core_health, fatal_report_work); health = container_of(work, struct mlx5_core_health, fatal_report_work);
priv = container_of(health, struct mlx5_priv, health); priv = container_of(health, struct mlx5_priv, health);
dev = container_of(priv, struct mlx5_core_dev, priv); dev = container_of(priv, struct mlx5_core_dev, priv);
devlink = priv_to_devlink(dev);
enter_error_state(dev, false); enter_error_state(dev, false);
if (IS_ERR_OR_NULL(health->fw_fatal_reporter)) { if (IS_ERR_OR_NULL(health->fw_fatal_reporter)) {
devl_lock(devlink);
if (mlx5_health_try_recover(dev)) if (mlx5_health_try_recover(dev))
mlx5_core_err(dev, "health recovery failed\n"); mlx5_core_err(dev, "health recovery failed\n");
devl_unlock(devlink);
return; return;
} }
fw_reporter_ctx.err_synd = health->synd; fw_reporter_ctx.err_synd = health->synd;
......
...@@ -1304,8 +1304,10 @@ static void mlx5_unload(struct mlx5_core_dev *dev) ...@@ -1304,8 +1304,10 @@ static void mlx5_unload(struct mlx5_core_dev *dev)
int mlx5_init_one(struct mlx5_core_dev *dev) int mlx5_init_one(struct mlx5_core_dev *dev)
{ {
struct devlink *devlink = priv_to_devlink(dev);
int err = 0; int err = 0;
devl_lock(devlink);
mutex_lock(&dev->intf_state_mutex); mutex_lock(&dev->intf_state_mutex);
dev->state = MLX5_DEVICE_STATE_UP; dev->state = MLX5_DEVICE_STATE_UP;
...@@ -1334,6 +1336,7 @@ int mlx5_init_one(struct mlx5_core_dev *dev) ...@@ -1334,6 +1336,7 @@ int mlx5_init_one(struct mlx5_core_dev *dev)
goto err_register; goto err_register;
mutex_unlock(&dev->intf_state_mutex); mutex_unlock(&dev->intf_state_mutex);
devl_unlock(devlink);
return 0; return 0;
err_register: err_register:
...@@ -1348,11 +1351,15 @@ int mlx5_init_one(struct mlx5_core_dev *dev) ...@@ -1348,11 +1351,15 @@ int mlx5_init_one(struct mlx5_core_dev *dev)
err_function: err_function:
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
mutex_unlock(&dev->intf_state_mutex); mutex_unlock(&dev->intf_state_mutex);
devl_unlock(devlink);
return err; return err;
} }
void mlx5_uninit_one(struct mlx5_core_dev *dev) void mlx5_uninit_one(struct mlx5_core_dev *dev)
{ {
struct devlink *devlink = priv_to_devlink(dev);
devl_lock(devlink);
mutex_lock(&dev->intf_state_mutex); mutex_lock(&dev->intf_state_mutex);
mlx5_unregister_device(dev); mlx5_unregister_device(dev);
...@@ -1371,13 +1378,15 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev) ...@@ -1371,13 +1378,15 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev)
mlx5_function_teardown(dev, true); mlx5_function_teardown(dev, true);
out: out:
mutex_unlock(&dev->intf_state_mutex); mutex_unlock(&dev->intf_state_mutex);
devl_unlock(devlink);
} }
int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery) int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery)
{ {
int err = 0; int err = 0;
u64 timeout; u64 timeout;
devl_assert_locked(priv_to_devlink(dev));
mutex_lock(&dev->intf_state_mutex); mutex_lock(&dev->intf_state_mutex);
if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
mlx5_core_warn(dev, "interface is up, NOP\n"); mlx5_core_warn(dev, "interface is up, NOP\n");
...@@ -1419,8 +1428,20 @@ int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery) ...@@ -1419,8 +1428,20 @@ int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery)
return err; return err;
} }
void mlx5_unload_one(struct mlx5_core_dev *dev) int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery)
{
struct devlink *devlink = priv_to_devlink(dev);
int ret;
devl_lock(devlink);
ret = mlx5_load_one_devl_locked(dev, recovery);
devl_unlock(devlink);
return ret;
}
void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev)
{ {
devl_assert_locked(priv_to_devlink(dev));
mutex_lock(&dev->intf_state_mutex); mutex_lock(&dev->intf_state_mutex);
mlx5_detach_device(dev); mlx5_detach_device(dev);
...@@ -1438,6 +1459,15 @@ void mlx5_unload_one(struct mlx5_core_dev *dev) ...@@ -1438,6 +1459,15 @@ void mlx5_unload_one(struct mlx5_core_dev *dev)
mutex_unlock(&dev->intf_state_mutex); mutex_unlock(&dev->intf_state_mutex);
} }
void mlx5_unload_one(struct mlx5_core_dev *dev)
{
struct devlink *devlink = priv_to_devlink(dev);
devl_lock(devlink);
mlx5_unload_one_devl_locked(dev);
devl_unlock(devlink);
}
static const int types[] = { static const int types[] = {
MLX5_CAP_GENERAL, MLX5_CAP_GENERAL,
MLX5_CAP_GENERAL_2, MLX5_CAP_GENERAL_2,
...@@ -1902,7 +1932,7 @@ MODULE_DEVICE_TABLE(pci, mlx5_core_pci_table); ...@@ -1902,7 +1932,7 @@ MODULE_DEVICE_TABLE(pci, mlx5_core_pci_table);
void mlx5_disable_device(struct mlx5_core_dev *dev) void mlx5_disable_device(struct mlx5_core_dev *dev)
{ {
mlx5_error_sw_reset(dev); mlx5_error_sw_reset(dev);
mlx5_unload_one(dev); mlx5_unload_one_devl_locked(dev);
} }
int mlx5_recover_device(struct mlx5_core_dev *dev) int mlx5_recover_device(struct mlx5_core_dev *dev)
...@@ -1913,7 +1943,7 @@ int mlx5_recover_device(struct mlx5_core_dev *dev) ...@@ -1913,7 +1943,7 @@ int mlx5_recover_device(struct mlx5_core_dev *dev)
return -EIO; return -EIO;
} }
return mlx5_load_one(dev, true); return mlx5_load_one_devl_locked(dev, true);
} }
static struct pci_driver mlx5_core_driver = { static struct pci_driver mlx5_core_driver = {
......
...@@ -290,7 +290,9 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev); ...@@ -290,7 +290,9 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev);
int mlx5_init_one(struct mlx5_core_dev *dev); int mlx5_init_one(struct mlx5_core_dev *dev);
void mlx5_uninit_one(struct mlx5_core_dev *dev); void mlx5_uninit_one(struct mlx5_core_dev *dev);
void mlx5_unload_one(struct mlx5_core_dev *dev); void mlx5_unload_one(struct mlx5_core_dev *dev);
void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev);
int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery); int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery);
int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery);
int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 function_id, void *out); int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 function_id, void *out);
......
...@@ -154,13 +154,16 @@ mlx5_device_disable_sriov(struct mlx5_core_dev *dev, int num_vfs, bool clear_vf) ...@@ -154,13 +154,16 @@ mlx5_device_disable_sriov(struct mlx5_core_dev *dev, int num_vfs, bool clear_vf)
static int mlx5_sriov_enable(struct pci_dev *pdev, int num_vfs) static int mlx5_sriov_enable(struct pci_dev *pdev, int num_vfs)
{ {
struct mlx5_core_dev *dev = pci_get_drvdata(pdev); struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
struct devlink *devlink = priv_to_devlink(dev);
int err; int err;
devl_lock(devlink);
err = mlx5_device_enable_sriov(dev, num_vfs); err = mlx5_device_enable_sriov(dev, num_vfs);
if (err) { if (err) {
mlx5_core_warn(dev, "mlx5_device_enable_sriov failed : %d\n", err); mlx5_core_warn(dev, "mlx5_device_enable_sriov failed : %d\n", err);
return err; return err;
} }
devl_unlock(devlink);
err = pci_enable_sriov(pdev, num_vfs); err = pci_enable_sriov(pdev, num_vfs);
if (err) { if (err) {
...@@ -173,10 +176,13 @@ static int mlx5_sriov_enable(struct pci_dev *pdev, int num_vfs) ...@@ -173,10 +176,13 @@ static int mlx5_sriov_enable(struct pci_dev *pdev, int num_vfs)
void mlx5_sriov_disable(struct pci_dev *pdev) void mlx5_sriov_disable(struct pci_dev *pdev)
{ {
struct mlx5_core_dev *dev = pci_get_drvdata(pdev); struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
struct devlink *devlink = priv_to_devlink(dev);
int num_vfs = pci_num_vf(dev->pdev); int num_vfs = pci_num_vf(dev->pdev);
pci_disable_sriov(pdev); pci_disable_sriov(pdev);
devl_lock(devlink);
mlx5_device_disable_sriov(dev, num_vfs, true); mlx5_device_disable_sriov(dev, num_vfs, true);
devl_unlock(devlink);
} }
int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs) int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs)
......
...@@ -699,6 +699,10 @@ struct devlink_region { ...@@ -699,6 +699,10 @@ struct devlink_region {
const struct devlink_region_ops *ops; const struct devlink_region_ops *ops;
const struct devlink_port_region_ops *port_ops; const struct devlink_port_region_ops *port_ops;
}; };
struct mutex snapshot_lock; /* protects snapshot_list,
* max_snapshots and cur_snapshots
* consistency.
*/
struct list_head snapshot_list; struct list_head snapshot_list;
u32 max_snapshots; u32 max_snapshots;
u32 cur_snapshots; u32 cur_snapshots;
...@@ -5894,21 +5898,28 @@ static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) ...@@ -5894,21 +5898,28 @@ static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
{ {
unsigned long count; unsigned long count;
void *p; void *p;
int err;
devl_assert_locked(devlink); xa_lock(&devlink->snapshot_ids);
p = xa_load(&devlink->snapshot_ids, id); p = xa_load(&devlink->snapshot_ids, id);
if (WARN_ON(!p)) if (WARN_ON(!p)) {
return -EINVAL; err = -EINVAL;
goto unlock;
}
if (WARN_ON(!xa_is_value(p))) if (WARN_ON(!xa_is_value(p))) {
return -EINVAL; err = -EINVAL;
goto unlock;
}
count = xa_to_value(p); count = xa_to_value(p);
count++; count++;
return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
GFP_KERNEL)); GFP_ATOMIC));
unlock:
xa_unlock(&devlink->snapshot_ids);
return err;
} }
/** /**
...@@ -5931,25 +5942,26 @@ static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) ...@@ -5931,25 +5942,26 @@ static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
unsigned long count; unsigned long count;
void *p; void *p;
devl_assert_locked(devlink); xa_lock(&devlink->snapshot_ids);
p = xa_load(&devlink->snapshot_ids, id); p = xa_load(&devlink->snapshot_ids, id);
if (WARN_ON(!p)) if (WARN_ON(!p))
return; goto unlock;
if (WARN_ON(!xa_is_value(p))) if (WARN_ON(!xa_is_value(p)))
return; goto unlock;
count = xa_to_value(p); count = xa_to_value(p);
if (count > 1) { if (count > 1) {
count--; count--;
xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
GFP_KERNEL); GFP_ATOMIC);
} else { } else {
/* If this was the last user, we can erase this id */ /* If this was the last user, we can erase this id */
xa_erase(&devlink->snapshot_ids, id); __xa_erase(&devlink->snapshot_ids, id);
} }
unlock:
xa_unlock(&devlink->snapshot_ids);
} }
/** /**
...@@ -5970,13 +5982,17 @@ static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) ...@@ -5970,13 +5982,17 @@ static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
*/ */
static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
{ {
devl_assert_locked(devlink); int err;
if (xa_load(&devlink->snapshot_ids, id)) xa_lock(&devlink->snapshot_ids);
if (xa_load(&devlink->snapshot_ids, id)) {
xa_unlock(&devlink->snapshot_ids);
return -EEXIST; return -EEXIST;
}
return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
GFP_KERNEL)); GFP_ATOMIC));
xa_unlock(&devlink->snapshot_ids);
return err;
} }
/** /**
...@@ -5997,8 +6013,6 @@ static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) ...@@ -5997,8 +6013,6 @@ static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
*/ */
static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
{ {
devl_assert_locked(devlink);
return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
xa_limit_32b, GFP_KERNEL); xa_limit_32b, GFP_KERNEL);
} }
...@@ -6011,7 +6025,7 @@ static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) ...@@ -6011,7 +6025,7 @@ static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
* Multiple snapshots can be created on a region. * Multiple snapshots can be created on a region.
* The @snapshot_id should be obtained using the getter function. * The @snapshot_id should be obtained using the getter function.
* *
* Must be called only while holding the devlink instance lock. * Must be called only while holding the region snapshot lock.
* *
* @region: devlink region of the snapshot * @region: devlink region of the snapshot
* @data: snapshot data * @data: snapshot data
...@@ -6025,7 +6039,7 @@ __devlink_region_snapshot_create(struct devlink_region *region, ...@@ -6025,7 +6039,7 @@ __devlink_region_snapshot_create(struct devlink_region *region,
struct devlink_snapshot *snapshot; struct devlink_snapshot *snapshot;
int err; int err;
devl_assert_locked(devlink); lockdep_assert_held(&region->snapshot_lock);
/* check if region can hold one more snapshot */ /* check if region can hold one more snapshot */
if (region->cur_snapshots == region->max_snapshots) if (region->cur_snapshots == region->max_snapshots)
...@@ -6063,7 +6077,7 @@ static void devlink_region_snapshot_del(struct devlink_region *region, ...@@ -6063,7 +6077,7 @@ static void devlink_region_snapshot_del(struct devlink_region *region,
{ {
struct devlink *devlink = region->devlink; struct devlink *devlink = region->devlink;
devl_assert_locked(devlink); lockdep_assert_held(&region->snapshot_lock);
devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL); devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
region->cur_snapshots--; region->cur_snapshots--;
...@@ -6242,11 +6256,15 @@ static int devlink_nl_cmd_region_del(struct sk_buff *skb, ...@@ -6242,11 +6256,15 @@ static int devlink_nl_cmd_region_del(struct sk_buff *skb,
if (!region) if (!region)
return -EINVAL; return -EINVAL;
mutex_lock(&region->snapshot_lock);
snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
if (!snapshot) if (!snapshot) {
mutex_unlock(&region->snapshot_lock);
return -EINVAL; return -EINVAL;
}
devlink_region_snapshot_del(region, snapshot); devlink_region_snapshot_del(region, snapshot);
mutex_unlock(&region->snapshot_lock);
return 0; return 0;
} }
...@@ -6294,9 +6312,12 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) ...@@ -6294,9 +6312,12 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
mutex_lock(&region->snapshot_lock);
if (region->cur_snapshots == region->max_snapshots) { if (region->cur_snapshots == region->max_snapshots) {
NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots"); NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
return -ENOSPC; err = -ENOSPC;
goto unlock;
} }
snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
...@@ -6305,17 +6326,18 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) ...@@ -6305,17 +6326,18 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use"); NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
return -EEXIST; err = -EEXIST;
goto unlock;
} }
err = __devlink_snapshot_id_insert(devlink, snapshot_id); err = __devlink_snapshot_id_insert(devlink, snapshot_id);
if (err) if (err)
return err; goto unlock;
} else { } else {
err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
if (err) { if (err) {
NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id"); NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
return err; goto unlock;
} }
} }
...@@ -6353,16 +6375,20 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) ...@@ -6353,16 +6375,20 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
goto err_notify; goto err_notify;
} }
mutex_unlock(&region->snapshot_lock);
return 0; return 0;
err_snapshot_create: err_snapshot_create:
region->ops->destructor(data); region->ops->destructor(data);
err_snapshot_capture: err_snapshot_capture:
__devlink_snapshot_id_decrement(devlink, snapshot_id); __devlink_snapshot_id_decrement(devlink, snapshot_id);
mutex_unlock(&region->snapshot_lock);
return err; return err;
err_notify: err_notify:
devlink_region_snapshot_del(region, snapshot); devlink_region_snapshot_del(region, snapshot);
unlock:
mutex_unlock(&region->snapshot_lock);
return err; return err;
} }
...@@ -7731,6 +7757,7 @@ int devlink_health_report(struct devlink_health_reporter *reporter, ...@@ -7731,6 +7757,7 @@ int devlink_health_report(struct devlink_health_reporter *reporter,
enum devlink_health_reporter_state prev_health_state; enum devlink_health_reporter_state prev_health_state;
struct devlink *devlink = reporter->devlink; struct devlink *devlink = reporter->devlink;
unsigned long recover_ts_threshold; unsigned long recover_ts_threshold;
int ret;
/* write a log message of the current error */ /* write a log message of the current error */
WARN_ON(!msg); WARN_ON(!msg);
...@@ -7764,11 +7791,14 @@ int devlink_health_report(struct devlink_health_reporter *reporter, ...@@ -7764,11 +7791,14 @@ int devlink_health_report(struct devlink_health_reporter *reporter,
mutex_unlock(&reporter->dump_lock); mutex_unlock(&reporter->dump_lock);
} }
if (reporter->auto_recover) if (!reporter->auto_recover)
return devlink_health_reporter_recover(reporter, return 0;
priv_ctx, NULL);
return 0; devl_lock(devlink);
ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL);
devl_unlock(devlink);
return ret;
} }
EXPORT_SYMBOL_GPL(devlink_health_report); EXPORT_SYMBOL_GPL(devlink_health_report);
...@@ -9443,8 +9473,7 @@ static const struct genl_small_ops devlink_nl_ops[] = { ...@@ -9443,8 +9473,7 @@ static const struct genl_small_ops devlink_nl_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_health_reporter_get_doit, .doit = devlink_nl_cmd_health_reporter_get_doit,
.dumpit = devlink_nl_cmd_health_reporter_get_dumpit, .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
DEVLINK_NL_FLAG_NO_LOCK,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
...@@ -9452,24 +9481,21 @@ static const struct genl_small_ops devlink_nl_ops[] = { ...@@ -9452,24 +9481,21 @@ static const struct genl_small_ops devlink_nl_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_health_reporter_set_doit, .doit = devlink_nl_cmd_health_reporter_set_doit,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
DEVLINK_NL_FLAG_NO_LOCK,
}, },
{ {
.cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_health_reporter_recover_doit, .doit = devlink_nl_cmd_health_reporter_recover_doit,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
DEVLINK_NL_FLAG_NO_LOCK,
}, },
{ {
.cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_health_reporter_diagnose_doit, .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
DEVLINK_NL_FLAG_NO_LOCK,
}, },
{ {
.cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
...@@ -9483,16 +9509,14 @@ static const struct genl_small_ops devlink_nl_ops[] = { ...@@ -9483,16 +9509,14 @@ static const struct genl_small_ops devlink_nl_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_health_reporter_dump_clear_doit, .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
DEVLINK_NL_FLAG_NO_LOCK,
}, },
{ {
.cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST, .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_health_reporter_test_doit, .doit = devlink_nl_cmd_health_reporter_test_doit,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
DEVLINK_NL_FLAG_NO_LOCK,
}, },
{ {
.cmd = DEVLINK_CMD_FLASH_UPDATE, .cmd = DEVLINK_CMD_FLASH_UPDATE,
...@@ -11300,6 +11324,7 @@ struct devlink_region *devl_region_create(struct devlink *devlink, ...@@ -11300,6 +11324,7 @@ struct devlink_region *devl_region_create(struct devlink *devlink,
region->ops = ops; region->ops = ops;
region->size = region_size; region->size = region_size;
INIT_LIST_HEAD(&region->snapshot_list); INIT_LIST_HEAD(&region->snapshot_list);
mutex_init(&region->snapshot_lock);
list_add_tail(&region->list, &devlink->region_list); list_add_tail(&region->list, &devlink->region_list);
devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
...@@ -11373,6 +11398,7 @@ devlink_port_region_create(struct devlink_port *port, ...@@ -11373,6 +11398,7 @@ devlink_port_region_create(struct devlink_port *port,
region->port_ops = ops; region->port_ops = ops;
region->size = region_size; region->size = region_size;
INIT_LIST_HEAD(&region->snapshot_list); INIT_LIST_HEAD(&region->snapshot_list);
mutex_init(&region->snapshot_lock);
list_add_tail(&region->list, &port->region_list); list_add_tail(&region->list, &port->region_list);
devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
...@@ -11402,6 +11428,7 @@ void devl_region_destroy(struct devlink_region *region) ...@@ -11402,6 +11428,7 @@ void devl_region_destroy(struct devlink_region *region)
devlink_region_snapshot_del(region, snapshot); devlink_region_snapshot_del(region, snapshot);
list_del(&region->list); list_del(&region->list);
mutex_destroy(&region->snapshot_lock);
devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
kfree(region); kfree(region);
...@@ -11442,13 +11469,7 @@ EXPORT_SYMBOL_GPL(devlink_region_destroy); ...@@ -11442,13 +11469,7 @@ EXPORT_SYMBOL_GPL(devlink_region_destroy);
*/ */
int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
{ {
int err; return __devlink_region_snapshot_id_get(devlink, id);
devl_lock(devlink);
err = __devlink_region_snapshot_id_get(devlink, id);
devl_unlock(devlink);
return err;
} }
EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
...@@ -11464,9 +11485,7 @@ EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); ...@@ -11464,9 +11485,7 @@ EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
*/ */
void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
{ {
devl_lock(devlink);
__devlink_snapshot_id_decrement(devlink, id); __devlink_snapshot_id_decrement(devlink, id);
devl_unlock(devlink);
} }
EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
...@@ -11485,13 +11504,11 @@ EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); ...@@ -11485,13 +11504,11 @@ EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
int devlink_region_snapshot_create(struct devlink_region *region, int devlink_region_snapshot_create(struct devlink_region *region,
u8 *data, u32 snapshot_id) u8 *data, u32 snapshot_id)
{ {
struct devlink *devlink = region->devlink;
int err; int err;
devl_lock(devlink); mutex_lock(&region->snapshot_lock);
err = __devlink_region_snapshot_create(region, data, snapshot_id); err = __devlink_region_snapshot_create(region, data, snapshot_id);
devl_unlock(devlink); mutex_unlock(&region->snapshot_lock);
return err; return err;
} }
EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment