]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
RDMA/mlx5: Implement DMABUF export ops
authorYishai Hadas <yishaih@nvidia.com>
Sun, 1 Feb 2026 14:34:06 +0000 (16:34 +0200)
committerLeon Romanovsky <leon@kernel.org>
Mon, 9 Feb 2026 04:50:41 +0000 (23:50 -0500)
Enable p2pdma on the mlx5 PCI device to allow DMABUF-based peer-to-peer
DMA mappings.

Add implementation of the mmap_get_pfns and pgoff_to_mmap_entry device
operations required for DMABUF support in the mlx5 RDMA driver.

The pgoff_to_mmap_entry operation converts a page offset to the
corresponding rdma_user_mmap_entry by extracting the command and index
from the offset and looking it up in the ucontext's mmap_xa.

The mmap_get_pfns operation retrieves the physical address and length
from the mmap entry and obtains the p2pdma provider for the underlying
PCI device, which is needed for peer-to-peer DMA operations with
DMABUFs.

Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
Link: https://patch.msgid.link/20260201-dmabuf-export-v3-3-da238b614fe3@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/mlx5/main.c

index eba023b7af0fa44279a65f59be3e1eaa4791b9b7..88cbd534771c9cdf9c09d0d8613152839c1f2c5f 100644 (file)
@@ -2454,6 +2454,70 @@ static int mlx5_ib_mmap_clock_info_page(struct mlx5_ib_dev *dev,
                              virt_to_page(dev->mdev->clock_info));
 }
 
+static int phys_addr_to_bar(struct pci_dev *pdev, phys_addr_t pa)
+{
+       resource_size_t start, end;
+       int bar;
+
+       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+               /* Skip BARs not present or not memory-mapped */
+               if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
+                       continue;
+
+               start = pci_resource_start(pdev, bar);
+               end = pci_resource_end(pdev, bar);
+
+               if (!start || !end)
+                       continue;
+
+               if (pa >= start && pa <= end)
+                       return bar;
+       }
+
+       return -1;
+}
+
+static int mlx5_ib_mmap_get_pfns(struct rdma_user_mmap_entry *entry,
+                                struct phys_vec *phys_vec,
+                                struct p2pdma_provider **provider)
+{
+       struct mlx5_user_mmap_entry *mentry = to_mmmap(entry);
+       struct pci_dev *pdev = to_mdev(entry->ucontext->device)->mdev->pdev;
+       int bar;
+
+       phys_vec->paddr = mentry->address;
+       phys_vec->len = entry->npages * PAGE_SIZE;
+
+       bar = phys_addr_to_bar(pdev, phys_vec->paddr);
+       if (bar < 0)
+               return -EINVAL;
+
+       *provider = pcim_p2pdma_provider(pdev, bar);
+       /* If the kernel was not compiled with CONFIG_PCI_P2PDMA the
+        * functionality is not supported.
+        */
+       if (!*provider)
+               return -EOPNOTSUPP;
+
+       return 0;
+}
+
+static struct rdma_user_mmap_entry *
+mlx5_ib_pgoff_to_mmap_entry(struct ib_ucontext *ucontext, off_t pg_off)
+{
+       unsigned long entry_pgoff;
+       unsigned long idx;
+       u8 command;
+
+       pg_off = pg_off >> PAGE_SHIFT;
+       command = get_command(pg_off);
+       idx = get_extended_index(pg_off);
+
+       entry_pgoff = command << 16 | idx;
+
+       return rdma_user_mmap_entry_get_pgoff(ucontext, entry_pgoff);
+}
+
 static void mlx5_ib_mmap_free(struct rdma_user_mmap_entry *entry)
 {
        struct mlx5_user_mmap_entry *mentry = to_mmmap(entry);
@@ -4419,7 +4483,13 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
        if (err)
                goto err_mp;
 
+       err = pcim_p2pdma_init(mdev->pdev);
+       if (err && err != -EOPNOTSUPP)
+               goto err_dd;
+
        return 0;
+err_dd:
+       mlx5_ib_data_direct_cleanup(dev);
 err_mp:
        mlx5_ib_cleanup_multiport_master(dev);
 err:
@@ -4471,11 +4541,13 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
        .map_mr_sg_pi = mlx5_ib_map_mr_sg_pi,
        .mmap = mlx5_ib_mmap,
        .mmap_free = mlx5_ib_mmap_free,
+       .mmap_get_pfns = mlx5_ib_mmap_get_pfns,
        .modify_cq = mlx5_ib_modify_cq,
        .modify_device = mlx5_ib_modify_device,
        .modify_port = mlx5_ib_modify_port,
        .modify_qp = mlx5_ib_modify_qp,
        .modify_srq = mlx5_ib_modify_srq,
+       .pgoff_to_mmap_entry = mlx5_ib_pgoff_to_mmap_entry,
        .pre_destroy_cq = mlx5_ib_pre_destroy_cq,
        .poll_cq = mlx5_ib_poll_cq,
        .post_destroy_cq = mlx5_ib_post_destroy_cq,