net/mlx5e: Don't create devices during unload flow
authorDmytro Linkin <dlinkin@nvidia.com>
Fri, 14 May 2021 08:14:19 +0000 (11:14 +0300)
committerSaeed Mahameed <saeedm@nvidia.com>
Wed, 16 Jun 2021 22:36:47 +0000 (15:36 -0700)
Running devlink reload command for port in switchdev mode cause
resources to corrupt: driver can't release allocated EQ and reclaim
memory pages, because "rdma" auxiliary device had add CQs which blocks
EQ from deletion.
Erroneous sequence happens during reload-down phase, and is following:

1. detach device - suspends auxiliary devices which support it, destroys
   others. During this step "eth-rep" and "rdma-rep" are destroyed,
   "eth" - suspended.
2. disable SRIOV - moves device to legacy mode; as part of disablement -
   rescans drivers. This step adds "rdma" auxiliary device.
3. destroy EQ table - <failure>.

Driver shouldn't create any device during unload flows. To handle that
implement MLX5_PRIV_FLAGS_DETACH flag, set it on device detach and unset
on device attach. If flag is set do no-op on drivers rescan.

Fixes: a925b5e309c9 ("net/mlx5: Register mlx5 devices to auxiliary virtual bus")
Signed-off-by: Dmytro Linkin <dlinkin@nvidia.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Reviewed-by: Roi Dayan <roid@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/dev.c
include/linux/mlx5/driver.h

index 8de118adfb544868172bf750c1e797285daa48ab..ceebfc20f65e5057261cf7599c374f84b7ca80dd 100644 (file)
@@ -303,6 +303,7 @@ int mlx5_attach_device(struct mlx5_core_dev *dev)
        int ret = 0, i;
 
        mutex_lock(&mlx5_intf_mutex);
+       priv->flags &= ~MLX5_PRIV_FLAGS_DETACH;
        for (i = 0; i < ARRAY_SIZE(mlx5_adev_devices); i++) {
                if (!priv->adev[i]) {
                        bool is_supported = false;
@@ -375,6 +376,7 @@ skip_suspend:
                del_adev(&priv->adev[i]->adev);
                priv->adev[i] = NULL;
        }
+       priv->flags |= MLX5_PRIV_FLAGS_DETACH;
        mutex_unlock(&mlx5_intf_mutex);
 }
 
@@ -463,6 +465,8 @@ int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev)
        struct mlx5_priv *priv = &dev->priv;
 
        lockdep_assert_held(&mlx5_intf_mutex);
+       if (priv->flags & MLX5_PRIV_FLAGS_DETACH)
+               return 0;
 
        delete_drivers(dev);
        if (priv->flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV)
index 020a8f7fdbdd43e3215d0ad9a8dcb6b9d228f9ea..f8902bcd91e2600d6f7b12c58307ee27569571f6 100644 (file)
@@ -542,6 +542,10 @@ struct mlx5_core_roce {
 enum {
        MLX5_PRIV_FLAGS_DISABLE_IB_ADEV = 1 << 0,
        MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV = 1 << 1,
+       /* Set during device detach to block any further devices
+        * creation/deletion on drivers rescan. Unset during device attach.
+        */
+       MLX5_PRIV_FLAGS_DETACH = 1 << 2,
 };
 
 struct mlx5_adev {