The timeout passed to hmm_range_fault_unlocked_timeout() is a relative retry budget for HMM's internal mmu-notifier retry loop. drm_gpusvm was still keeping an absolute deadline around the outer driver retry logic and passing the remaining time into HMM. Pass HMM_RANGE_DEFAULT_TIMEOUT directly to hmm_range_fault_unlocked_timeout() on each HMM fault attempt instead. If HMM succeeds but the later drm_gpusvm-side mmu_interval_read_retry() check observes an invalidation, retry with a fresh HMM retry budget. This keeps the timeout focused on repeated notifier retries inside HMM, while avoiding an outer deadline that also accounts unrelated driver-side work after HMM has made progress. Signed-off-by: Stanislav Kinsburskii --- drivers/gpu/drm/drm_gpusvm.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index b8f2dd9982f5..76e8a0028c7f 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -852,8 +852,7 @@ enum drm_gpusvm_scan_result drm_gpusvm_scan_mm(struct drm_gpusvm_range *range, .end = end, .dev_private_owner = dev_private_owner, }; - unsigned long timeout = - jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); + unsigned long timeout = msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); enum drm_gpusvm_scan_result state = DRM_GPUSVM_SCAN_UNPOPULATED, new_state; unsigned long *pfns; unsigned long npages = npages_in_range(start, end); @@ -867,8 +866,7 @@ enum drm_gpusvm_scan_result drm_gpusvm_scan_mm(struct drm_gpusvm_range *range, hmm_range.hmm_pfns = pfns; retry: - err = hmm_range_fault_unlocked_timeout(&hmm_range, - max(timeout - jiffies, 1L)); + err = hmm_range_fault_unlocked_timeout(&hmm_range, timeout); if (err) goto err_free; @@ -1459,8 +1457,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, .dev_private_owner = ctx->device_private_page_owner, }; void *zdd; - unsigned long timeout = - jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); + unsigned long timeout = msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); unsigned long i, j; unsigned long npages = npages_in_range(pages_start, pages_end); unsigned long num_dma_mapped; @@ -1478,9 +1475,6 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, return -EINVAL; retry: - if (time_after(jiffies, timeout)) - return -EBUSY; - hmm_range.notifier_seq = mmu_interval_read_begin(notifier); if (drm_gpusvm_pages_valid_unlocked(gpusvm, svm_pages)) goto set_seqno; @@ -1495,8 +1489,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, } hmm_range.hmm_pfns = pfns; - err = hmm_range_fault_unlocked_timeout(&hmm_range, - max_t(long, timeout - jiffies, 1)); + err = hmm_range_fault_unlocked_timeout(&hmm_range, timeout); mmput(mm); if (err) goto err_free; @@ -1718,8 +1711,7 @@ int drm_gpusvm_range_evict(struct drm_gpusvm *gpusvm, .end = drm_gpusvm_range_end(range), .dev_private_owner = NULL, }; - unsigned long timeout = - jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); + unsigned long timeout = msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); unsigned long *pfns; unsigned long npages = npages_in_range(drm_gpusvm_range_start(range), drm_gpusvm_range_end(range)); @@ -1734,8 +1726,7 @@ int drm_gpusvm_range_evict(struct drm_gpusvm *gpusvm, return -ENOMEM; hmm_range.hmm_pfns = pfns; - err = hmm_range_fault_unlocked_timeout(&hmm_range, - max_t(long, timeout - jiffies, 1)); + err = hmm_range_fault_unlocked_timeout(&hmm_range, timeout); kvfree(pfns); mmput(mm);