aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlaa Hleihel <alaa@mellanox.com>2019-05-19 11:11:49 +0300
committerPaul Gortmaker <paul.gortmaker@windriver.com>2019-09-16 12:21:46 -0400
commite217f8d4d558f934e7ae0f83af12329e4dec23af (patch)
tree71415f0129b880d3a04f92d0305365cccab5f8f5
parente688ac750c0bf677ba9ac4bb306a82d288de862e (diff)
downloadlinux-yocto-e217f8d4d558f934e7ae0f83af12329e4dec23af.tar.gz
linux-yocto-e217f8d4d558f934e7ae0f83af12329e4dec23af.tar.bz2
linux-yocto-e217f8d4d558f934e7ae0f83af12329e4dec23af.zip
net/mlx5: Avoid reloading already removed devices
commit dd80857bf388abd0c64dd3aa4fbf7d407deba819 upstream. Prior to reloading a device we must first verify that it was not already removed. Otherwise, the attempt to remove the device will do nothing, and in that case we will end up proceeding with adding an new device that no one was expecting to remove, leaving behind used resources such as EQs that causes a failure to destroy comp EQs and syndrome (0x30f433). Fix that by making sure that we try to remove and add a device (based on a protocol) only if the device is already added. Fixes: c5447c70594b ("net/mlx5: E-Switch, Reload IB interface when switching devlink modes") Signed-off-by: Alaa Hleihel <alaa@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/dev.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
index 37ba7c78859d..1c225be9c7db 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
@@ -342,11 +342,32 @@ void mlx5_unregister_interface(struct mlx5_interface *intf)
}
EXPORT_SYMBOL(mlx5_unregister_interface);
+/* Must be called with intf_mutex held */
+static bool mlx5_has_added_dev_by_protocol(struct mlx5_core_dev *mdev, int protocol)
+{
+ struct mlx5_device_context *dev_ctx;
+ struct mlx5_interface *intf;
+ bool found = false;
+
+ list_for_each_entry(intf, &intf_list, list) {
+ if (intf->protocol == protocol) {
+ dev_ctx = mlx5_get_device(intf, &mdev->priv);
+ if (dev_ctx && test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state))
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
+
void mlx5_reload_interface(struct mlx5_core_dev *mdev, int protocol)
{
mutex_lock(&mlx5_intf_mutex);
- mlx5_remove_dev_by_protocol(mdev, protocol);
- mlx5_add_dev_by_protocol(mdev, protocol);
+ if (mlx5_has_added_dev_by_protocol(mdev, protocol)) {
+ mlx5_remove_dev_by_protocol(mdev, protocol);
+ mlx5_add_dev_by_protocol(mdev, protocol);
+ }
mutex_unlock(&mlx5_intf_mutex);
}