nouveau_range_fault() takes mmap_read_lock() only to call hmm_range_fault(). It also keeps a single HMM_RANGE_DEFAULT_TIMEOUT deadline across both HMM -EBUSY retries and post-fault mmu_interval_read_retry() retries.
Use hmm_range_fault_unlocked_timeout() instead. The HMM helper now owns the mmap lock and refreshes range->notifier_seq for its internal retries. Nouveau keeps its existing absolute deadline in the outer loop and passes the remaining jiffies to the helper for each fault attempt, so retries caused by mmu_interval_read_retry() do not reset the overall retry budget. Nouveau still validates the interval notifier sequence while holding svmm->mutex before programming the GPU mapping. Signed-off-by: Stanislav Kinsburskii <[email protected]> --- drivers/gpu/drm/nouveau/nouveau_svm.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index dcc92131488e..ba93273341af 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -683,15 +683,10 @@ static int nouveau_range_fault(struct nouveau_svmm *svmm, goto out; } - range.notifier_seq = mmu_interval_read_begin(range.notifier); - mmap_read_lock(mm); - ret = hmm_range_fault(&range); - mmap_read_unlock(mm); - if (ret) { - if (ret == -EBUSY) - continue; + ret = hmm_range_fault_unlocked_timeout(&range, + max_t(long, timeout - jiffies, 1UL)); + if (ret) goto out; - } mutex_lock(&svmm->mutex); if (mmu_interval_read_retry(range.notifier,
