]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
RDMA/rxe: Break endless pagefault loop for RO pages
authorLeon Romanovsky <leonro@nvidia.com>
Thu, 22 May 2025 11:36:18 +0000 (14:36 +0300)
committerLeon Romanovsky <leon@kernel.org>
Thu, 22 May 2025 16:05:21 +0000 (12:05 -0400)
RO pages has "perm" equal to 0, that caused to the situation
where such pages were marked as needed to have fault and caused
to infinite loop.

Fixes: eedd5b1276e7 ("RDMA/umem: Store ODP access mask information in PFN")
Reported-by: Daisuke Matsuda <dskmtsd@gmail.com>
Closes: https://lore.kernel.org/all/3016329a-4edd-4550-862f-b298a1b79a39@gmail.com/
Link: https://patch.msgid.link/096fab178d48ed86942ee22eafe9be98e29092aa.1747913377.git.leonro@nvidia.com
Tested-by: Daisuke Matsuda <dskmtsd@gmail.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
drivers/infiniband/sw/rxe/rxe_odp.c

index a1416626f61a5520f1c7805e187c83d4e6b7a289..dbc5a5600eb7874c73be50b350ee9dace0fa85ec 100644 (file)
@@ -124,8 +124,8 @@ int rxe_odp_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length,
        return err;
 }
 
-static inline bool rxe_check_pagefault(struct ib_umem_odp *umem_odp,
-                                      u64 iova, int length, u32 perm)
+static inline bool rxe_check_pagefault(struct ib_umem_odp *umem_odp, u64 iova,
+                                      int length)
 {
        bool need_fault = false;
        u64 addr;
@@ -137,7 +137,7 @@ static inline bool rxe_check_pagefault(struct ib_umem_odp *umem_odp,
        while (addr < iova + length) {
                idx = (addr - ib_umem_start(umem_odp)) >> umem_odp->page_shift;
 
-               if (!(umem_odp->map.pfn_list[idx] & perm)) {
+               if (!(umem_odp->map.pfn_list[idx] & HMM_PFN_VALID)) {
                        need_fault = true;
                        break;
                }
@@ -161,18 +161,14 @@ static int rxe_odp_map_range_and_lock(struct rxe_mr *mr, u64 iova, int length, u
 {
        struct ib_umem_odp *umem_odp = to_ib_umem_odp(mr->umem);
        bool need_fault;
-       u64 perm = 0;
        int err;
 
        if (unlikely(length < 1))
                return -EINVAL;
 
-       if (!(flags & RXE_PAGEFAULT_RDONLY))
-               perm |= HMM_PFN_WRITE;
-
        mutex_lock(&umem_odp->umem_mutex);
 
-       need_fault = rxe_check_pagefault(umem_odp, iova, length, perm);
+       need_fault = rxe_check_pagefault(umem_odp, iova, length);
        if (need_fault) {
                mutex_unlock(&umem_odp->umem_mutex);
 
@@ -182,7 +178,7 @@ static int rxe_odp_map_range_and_lock(struct rxe_mr *mr, u64 iova, int length, u
                if (err < 0)
                        return err;
 
-               need_fault = rxe_check_pagefault(umem_odp, iova, length, perm);
+               need_fault = rxe_check_pagefault(umem_odp, iova, length);
                if (need_fault)
                        return -EFAULT;
        }