[PATCH mlx5-next 01/10] RDMA/mlx5: Notify data direct users via a notifier chain on unbind
From: Tariq Toukan <tariqt@nvidia.com>
Date: 2026-09-17 11:15:35
Also in:
linux-rdma, lkml
Subsystem:
infiniband subsystem, mellanox mlx5 ib driver, the rest · Maintainers:
Jason Gunthorpe, Leon Romanovsky, Linus Torvalds
From: Dragos Tatulea <dtatulea@nvidia.com> Currently during unbind, data direct code calls mlx5_ib_data_direct_unbind() directly. To make the unbind notification generic and support multiple users, deliver an MLX5_DATA_DIRECT_UNBIND event through a blocking_notifier chain kept per registration. Users register a notifier_block via mlx5_data_direct_ib_reg(); mlx5_ib embeds one in struct mlx5_ib_dev and, from its notifier callback, runs the existing mlx5_ib_data_direct_unbind() teardown. This patch doesn't introduce any functional changes. Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com> Reviewed-by: Cosmin Ratiu <redacted> Reviewed-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> --- drivers/infiniband/hw/mlx5/data_direct.c | 17 ++++++++++++++--- drivers/infiniband/hw/mlx5/data_direct.h | 12 ++++++++++-- drivers/infiniband/hw/mlx5/main.c | 17 +++++++++++++++-- drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 + 4 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/data_direct.c b/drivers/infiniband/hw/mlx5/data_direct.c
index d57484245c38..04affdbdcb12 100644
--- a/drivers/infiniband/hw/mlx5/data_direct.c
+++ b/drivers/infiniband/hw/mlx5/data_direct.c@@ -4,6 +4,9 @@ */ #include "mlx5_ib.h" + +#include <linux/notifier.h> + #include "data_direct.h" static LIST_HEAD(mlx5_data_direct_dev_list);
@@ -18,6 +21,7 @@ struct mlx5_data_direct_registration { struct mlx5_ib_dev *ibdev; char vuid[MLX5_ST_SZ_BYTES(array1024_auto) + 1]; struct list_head list; + struct blocking_notifier_head users; }; static const struct pci_device_id mlx5_data_direct_pci_table[] = {
@@ -78,7 +82,8 @@ static int mlx5_data_direct_set_dma_caps(struct pci_dev *pdev) return 0; } -int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid) +int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid, + struct notifier_block *nb) { struct mlx5_data_direct_registration *reg; struct mlx5_data_direct_dev *dev;
@@ -89,6 +94,8 @@ int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid) reg->ibdev = ibdev; strscpy(reg->vuid, vuid); + BLOCKING_INIT_NOTIFIER_HEAD(®->users); + blocking_notifier_chain_register(®->users, nb); mutex_lock(&mlx5_data_direct_mutex); list_for_each_entry(dev, &mlx5_data_direct_dev_list, list) {
@@ -106,13 +113,15 @@ int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid) return 0; } -void mlx5_data_direct_ib_unreg(struct mlx5_ib_dev *ibdev) +void mlx5_data_direct_ib_unreg(struct mlx5_ib_dev *ibdev, + struct notifier_block *nb) { struct mlx5_data_direct_registration *reg; mutex_lock(&mlx5_data_direct_mutex); list_for_each_entry(reg, &mlx5_data_direct_reg_list, list) { if (reg->ibdev == ibdev) { + blocking_notifier_chain_unregister(®->users, nb); list_del(®->list); kfree(reg); goto end;
@@ -150,7 +159,9 @@ static void mlx5_data_direct_dev_unreg(struct mlx5_data_direct_dev *dev) list_del(&dev->list); list_for_each_entry(reg, &mlx5_data_direct_reg_list, list) { if (strcmp(dev->vuid, reg->vuid) == 0) - mlx5_ib_data_direct_unbind(reg->ibdev); + blocking_notifier_call_chain(®->users, + MLX5_DATA_DIRECT_UNBIND, + NULL); } mutex_unlock(&mlx5_data_direct_mutex); }
diff --git a/drivers/infiniband/hw/mlx5/data_direct.h b/drivers/infiniband/hw/mlx5/data_direct.h
index 2fd2bdbe8f69..a9bb471949e2 100644
--- a/drivers/infiniband/hw/mlx5/data_direct.h
+++ b/drivers/infiniband/hw/mlx5/data_direct.h@@ -6,8 +6,14 @@ #ifndef _MLX5_IB_DATA_DIRECT_H #define _MLX5_IB_DATA_DIRECT_H +#include <linux/notifier.h> + struct mlx5_ib_dev; +enum mlx5_data_direct_event { + MLX5_DATA_DIRECT_UNBIND, +}; + struct mlx5_data_direct_dev { struct device *device; struct pci_dev *pdev;
@@ -15,8 +21,10 @@ struct mlx5_data_direct_dev { struct list_head list; }; -int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid); -void mlx5_data_direct_ib_unreg(struct mlx5_ib_dev *ibdev); +int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid, + struct notifier_block *nb); +void mlx5_data_direct_ib_unreg(struct mlx5_ib_dev *ibdev, + struct notifier_block *nb); int mlx5_data_direct_driver_register(void); void mlx5_data_direct_driver_unregister(void);
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 02809114fc79..547275dfa40e 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c@@ -4019,6 +4019,18 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev, return false; } +static int mlx5_ib_data_direct_event(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct mlx5_ib_dev *dev = + container_of(nb, struct mlx5_ib_dev, data_direct_nb); + + if (action == MLX5_DATA_DIRECT_UNBIND) + mlx5_ib_data_direct_unbind(dev); + + return NOTIFY_OK; +} + static int mlx5_ib_data_direct_init(struct mlx5_ib_dev *dev) { char vuid[MLX5_ST_SZ_BYTES(array1024_auto) + 1] = {};
@@ -4037,7 +4049,8 @@ static int mlx5_ib_data_direct_init(struct mlx5_ib_dev *dev) return ret; INIT_LIST_HEAD(&dev->data_direct_mr_list); - ret = mlx5_data_direct_ib_reg(dev, vuid); + dev->data_direct_nb.notifier_call = mlx5_ib_data_direct_event; + ret = mlx5_data_direct_ib_reg(dev, vuid, &dev->data_direct_nb); if (ret) mlx5_ib_free_data_direct_resources(dev);
@@ -4050,7 +4063,7 @@ static void mlx5_ib_data_direct_cleanup(struct mlx5_ib_dev *dev) !MLX5_CAP_GEN_2(dev->mdev, query_vuid)) return; - mlx5_data_direct_ib_unreg(dev); + mlx5_data_direct_ib_unreg(dev, &dev->data_direct_nb); mlx5_ib_free_data_direct_resources(dev); }
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 522984d958bb..97d2aa79e95d 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h@@ -1131,6 +1131,7 @@ struct mlx5_ib_dev { spinlock_t reset_flow_resource_lock; struct list_head qp_list; struct list_head data_direct_mr_list; + struct notifier_block data_direct_nb; /* Array with num_ports elements */ struct mlx5_ib_port *port; struct mlx5_sq_bfreg bfreg;
--
2.44.0