Commit 734dc065 authored by Daniel Jurgens's avatar Daniel Jurgens Committed by Jason Gunthorpe

net/mlx5: Fix race for multiple RoCE enable

There are two potential problems with the existing implementation.

1. Enable and disable can race after the atomic operations.
2. If a command fails the refcount is left in an inconsistent state.

Introduce a lock and perform error checking.

Fixes: a6f7d2af ("net/mlx5: Add support for multiple RoCE enable")
Signed-off-by: default avatarDaniel Jurgens <danielj@mellanox.com>
Reviewed-by: default avatarParav Pandit <parav@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 776a3906
......@@ -36,6 +36,9 @@
#include <linux/mlx5/vport.h>
#include "mlx5_core.h"
/* Mutex to hold while enabling or disabling RoCE */
static DEFINE_MUTEX(mlx5_roce_en_lock);
static int _mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod,
u16 vport, u32 *out, int outlen)
{
......@@ -988,17 +991,35 @@ static int mlx5_nic_vport_update_roce_state(struct mlx5_core_dev *mdev,
int mlx5_nic_vport_enable_roce(struct mlx5_core_dev *mdev)
{
if (atomic_inc_return(&mdev->roce.roce_en) != 1)
return 0;
return mlx5_nic_vport_update_roce_state(mdev, MLX5_VPORT_ROCE_ENABLED);
int err = 0;
mutex_lock(&mlx5_roce_en_lock);
if (!mdev->roce.roce_en)
err = mlx5_nic_vport_update_roce_state(mdev, MLX5_VPORT_ROCE_ENABLED);
if (!err)
mdev->roce.roce_en++;
mutex_unlock(&mlx5_roce_en_lock);
return err;
}
EXPORT_SYMBOL_GPL(mlx5_nic_vport_enable_roce);
int mlx5_nic_vport_disable_roce(struct mlx5_core_dev *mdev)
{
if (atomic_dec_return(&mdev->roce.roce_en) != 0)
return 0;
return mlx5_nic_vport_update_roce_state(mdev, MLX5_VPORT_ROCE_DISABLED);
int err = 0;
mutex_lock(&mlx5_roce_en_lock);
if (mdev->roce.roce_en) {
mdev->roce.roce_en--;
if (mdev->roce.roce_en == 0)
err = mlx5_nic_vport_update_roce_state(mdev, MLX5_VPORT_ROCE_DISABLED);
if (err)
mdev->roce.roce_en++;
}
mutex_unlock(&mlx5_roce_en_lock);
return err;
}
EXPORT_SYMBOL_GPL(mlx5_nic_vport_disable_roce);
......
......@@ -835,7 +835,7 @@ struct mlx5_core_dev {
struct mlx5e_resources mlx5e_res;
struct {
struct mlx5_rsvd_gids reserved_gids;
atomic_t roce_en;
u32 roce_en;
} roce;
#ifdef CONFIG_MLX5_FPGA
struct mlx5_fpga_device *fpga;
......
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