]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/umem: Use consistent DMA attributes when unmapping entries
authorLeon Romanovsky <leonro@nvidia.com>
Mon, 23 Mar 2026 20:10:18 +0000 (22:10 +0200)
committerLeon Romanovsky <leon@kernel.org>
Mon, 30 Mar 2026 17:47:45 +0000 (13:47 -0400)
The DMA API expects that mapping and unmapping use the same DMA
attributes. The RDMA umem code did not meet this requirement, so fix
the mismatch.

Fixes: f03d9fadfe13 ("RDMA/core: Add weak ordering dma attr to dma mapping")
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
drivers/infiniband/core/umem.c
include/rdma/ib_umem.h

index 1b6c28f090e381b08acff7bdf9182b5345222c82..786fa1aa8e552bfbb87f87b3f1e390a767d17406 100644 (file)
@@ -55,8 +55,7 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
 
        if (dirty)
                ib_dma_unmap_sgtable_attrs(dev, &umem->sgt_append.sgt,
-                                          DMA_BIDIRECTIONAL,
-                                          DMA_ATTR_REQUIRE_COHERENT);
+                                          DMA_BIDIRECTIONAL, umem->dma_attrs);
 
        for_each_sgtable_sg(&umem->sgt_append.sgt, sg, i) {
                unpin_user_page_range_dirty_lock(sg_page(sg),
@@ -170,7 +169,6 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
        unsigned long lock_limit;
        unsigned long new_pinned;
        unsigned long cur_base;
-       unsigned long dma_attr = DMA_ATTR_REQUIRE_COHERENT;
        struct mm_struct *mm;
        unsigned long npages;
        int pinned, ret;
@@ -203,6 +201,10 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
        umem->iova = addr;
        umem->writable   = ib_access_writable(access);
        umem->owning_mm = mm = current->mm;
+       umem->dma_attrs = DMA_ATTR_REQUIRE_COHERENT;
+       if (access & IB_ACCESS_RELAXED_ORDERING)
+               umem->dma_attrs |= DMA_ATTR_WEAK_ORDERING;
+
        mmgrab(mm);
 
        page_list = (struct page **) __get_free_page(GFP_KERNEL);
@@ -255,11 +257,8 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
                }
        }
 
-       if (access & IB_ACCESS_RELAXED_ORDERING)
-               dma_attr |= DMA_ATTR_WEAK_ORDERING;
-
        ret = ib_dma_map_sgtable_attrs(device, &umem->sgt_append.sgt,
-                                      DMA_BIDIRECTIONAL, dma_attr);
+                                      DMA_BIDIRECTIONAL, umem->dma_attrs);
        if (ret)
                goto umem_release;
        goto out;
index 38414281a686b01af365b39d2ddc882a1dda89c9..2ad52cc1d52bdd910a5a2d87c29ce5944ae6d12b 100644 (file)
@@ -18,6 +18,7 @@ struct ib_umem {
        u64 iova;
        size_t                  length;
        unsigned long           address;
+       unsigned long           dma_attrs;
        u32 writable : 1;
        u32 is_odp : 1;
        u32 is_dmabuf : 1;