[PATCH mlx5-next 07/10] RDMA/mlx5: Extract IB specific lock out of data direct
From: Tariq Toukan
Date: Thu Sep 17 2026 - 07:33:10 EST
From: Dragos Tatulea <dtatulea@xxxxxxxxxx>
The data_direct_lock from struct mlx5_ib_dev is an IB specific lock.
It protects from unbind while mlx5_data_direct_dev is being accessed.
So move data_direct_lock out of the generic bind/unbind functions
and into the IB specific notifier callback.
data_direct_dev can be set during bind/unbind with a simple WRITE_ONCE,
the lock is no longer needed.
Each user of the data direct registration API has to do their own
locking if necessary.
During unbind, the data_direct_dev is set to NULL before calling the
notifiers to avoid multiple users still accessing the data_direct_dev
while unbind is in progress. This is to avoid another data
direct specific lock which can lead to lock ordering issues.
This patch has no functional changes.
Signed-off-by: Dragos Tatulea <dtatulea@xxxxxxxxxx>
Reviewed-by: Cosmin Ratiu <cratiu@xxxxxxxxxx>
Reviewed-by: Leon Romanovsky <leonro@xxxxxxxxxx>
Signed-off-by: Tariq Toukan <tariqt@xxxxxxxxxx>
---
drivers/infiniband/hw/mlx5/data_direct.c | 8 ++------
drivers/infiniband/hw/mlx5/main.c | 2 ++
drivers/infiniband/hw/mlx5/mlx5_ib.h | 4 +++-
drivers/infiniband/hw/mlx5/mr.c | 2 +-
drivers/infiniband/hw/mlx5/std_types.c | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/data_direct.c b/drivers/infiniband/hw/mlx5/data_direct.c
index f871e3ce9f73..16afacdd3601 100644
--- a/drivers/infiniband/hw/mlx5/data_direct.c
+++ b/drivers/infiniband/hw/mlx5/data_direct.c
@@ -197,9 +197,7 @@ mlx5_data_direct_get_reg(struct mlx5_ib_dev *ibdev)
static void mlx5_data_direct_bind(struct mlx5_ib_dev *ibdev,
struct mlx5_data_direct_dev *dev)
{
- mutex_lock(&ibdev->data_direct_lock);
- ibdev->data_direct_dev = dev;
- mutex_unlock(&ibdev->data_direct_lock);
+ WRITE_ONCE(ibdev->data_direct_dev, dev);
}
static void
@@ -207,11 +205,9 @@ mlx5_data_direct_do_unbind(struct mlx5_data_direct_registration *reg)
{
struct mlx5_ib_dev *ibdev = reg->ibdev;
- mutex_lock(&ibdev->data_direct_lock);
+ WRITE_ONCE(ibdev->data_direct_dev, NULL);
blocking_notifier_call_chain(®->users, MLX5_DATA_DIRECT_UNBIND,
NULL);
- ibdev->data_direct_dev = NULL;
- mutex_unlock(&ibdev->data_direct_lock);
}
int mlx5_data_direct_init(struct mlx5_ib_dev *ibdev)
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index d0141509870a..cefbcc816651 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -3948,7 +3948,9 @@ static int mlx5_ib_data_direct_event(struct notifier_block *nb,
if (action != MLX5_DATA_DIRECT_UNBIND)
return NOTIFY_DONE;
+ mutex_lock(&dev->data_direct_lock);
mlx5_ib_revoke_data_direct_mrs(dev);
+ mutex_unlock(&dev->data_direct_lock);
return NOTIFY_OK;
}
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index e56f3eee7ba1..8792e10340c5 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -1092,7 +1092,9 @@ struct mlx5_ib_dev {
struct ib_device ib_dev;
struct mlx5_core_dev *mdev;
struct mlx5_data_direct_dev *data_direct_dev;
- /* protect accessing data_direct_dev */
+ /* Protects data_direct_mr_list and serializes mr
+ * registration/deregistration with data direct device unbind.
+ */
struct mutex data_direct_lock;
struct notifier_block mdev_events;
struct notifier_block sys_error_events;
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index e6b74955d95d..1fc61a680f8a 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -997,7 +997,7 @@ reg_user_mr_dmabuf_by_data_direct(struct ib_pd *pd, u64 offset,
return ERR_PTR(-EOPNOTSUPP);
mutex_lock(&dev->data_direct_lock);
- data_direct_dev = dev->data_direct_dev;
+ data_direct_dev = READ_ONCE(dev->data_direct_dev);
if (!data_direct_dev) {
ret = -EINVAL;
goto end;
diff --git a/drivers/infiniband/hw/mlx5/std_types.c b/drivers/infiniband/hw/mlx5/std_types.c
index 1ee31611b4b3..df949fa634c9 100644
--- a/drivers/infiniband/hw/mlx5/std_types.c
+++ b/drivers/infiniband/hw/mlx5/std_types.c
@@ -203,7 +203,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH)(
return PTR_ERR(c);
dev = to_mdev(c->ibucontext.device);
mutex_lock(&dev->data_direct_lock);
- data_direct_dev = dev->data_direct_dev;
+ data_direct_dev = READ_ONCE(dev->data_direct_dev);
if (!data_direct_dev) {
ret = -ENODEV;
goto end;
--
2.44.0