ib_umem_odp_map_dma_and_lock() takes mmap_read_lock() only around
hmm_range_fault(), then retries -EBUSY until HMM_RANGE_DEFAULT_TIMEOUT
expires.

Use hmm_range_fault_unlocked_timeout() instead. The HMM helper now owns
the mmap lock and refreshes range->notifier_seq for its internal retries.
ODP keeps using HMM_RANGE_DEFAULT_TIMEOUT for each HMM fault attempt,
while interval invalidation retries continue to be handled by the existing
outer loop.

ODP still validates the interval notifier sequence while holding umem_mutex
before DMA mapping pages.

Signed-off-by: Stanislav Kinsburskii <[email protected]>
---
 drivers/infiniband/core/umem_odp.c |   18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/infiniband/core/umem_odp.c 
b/drivers/infiniband/core/umem_odp.c
index 404fa1cc3254..9cc21cd762d9 100644
--- a/drivers/infiniband/core/umem_odp.c
+++ b/drivers/infiniband/core/umem_odp.c
@@ -329,7 +329,7 @@ int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp 
*umem_odp, u64 user_virt,
        struct mm_struct *owning_mm = umem_odp->umem.owning_mm;
        int pfn_index, dma_index, ret = 0, start_idx;
        unsigned int page_shift, hmm_order, pfn_start_idx;
-       unsigned long num_pfns, current_seq;
+       unsigned long num_pfns;
        struct hmm_range range = {};
        unsigned long timeout;
 
@@ -363,26 +363,18 @@ int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp 
*umem_odp, u64 user_virt,
        }
 
        range.hmm_pfns = &(umem_odp->map.pfn_list[pfn_start_idx]);
-       timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
+       timeout = msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
 
 retry:
-       current_seq = range.notifier_seq =
-               mmu_interval_read_begin(&umem_odp->notifier);
-
-       mmap_read_lock(owning_mm);
-       ret = hmm_range_fault(&range);
-       mmap_read_unlock(owning_mm);
-       if (unlikely(ret)) {
-               if (ret == -EBUSY && !time_after(jiffies, timeout))
-                       goto retry;
+       ret = hmm_range_fault_unlocked_timeout(&range, timeout);
+       if (unlikely(ret))
                goto out_put_mm;
-       }
 
        start_idx = (range.start - ib_umem_start(umem_odp)) >> page_shift;
        dma_index = start_idx;
 
        mutex_lock(&umem_odp->umem_mutex);
-       if (mmu_interval_read_retry(&umem_odp->notifier, current_seq)) {
+       if (mmu_interval_read_retry(&umem_odp->notifier, range.notifier_seq)) {
                mutex_unlock(&umem_odp->umem_mutex);
                goto retry;
        }



Reply via email to