On Thu, Aug 27, 2026 at 03:14:45PM +0800, Honglei Huang wrote: > Make the HMM fault step of drm_gpusvm_get_pages(), including its -EBUSY > retry loop, into a helper drm_gpusvm_hmm_fault(). The existing logic of > the public drm_gpusvm_get_pages() is not changed, only relocated, so > there is no functional change. Keeping the retry loop in common code > also means drivers never have to open-code their own fault/retry loop. > > A single fault can later be shared by several drm_gpusvm_pages instances > that mirror the same CPU range. This prepares get_pages() to split the > shared MM-level fault from the per-device DMA mapping. No functional > change intended. >
I think you might want to just wait on this until Sunday for this series. I think this patch [1] is in the core MM tree so when drm-tip moves to 7.3.rc1, Sunday, we will have a version of this helper to core MM used in gpusvm. Matt [1] https://lore.freedesktop.org/nouveau/[email protected]/T/#m68f663ce3e802d7692363c70e6364569134cd6c7 > Suggested-by: Matthew Brost <[email protected]> > Signed-off-by: Honglei Huang <[email protected]> > --- > drivers/gpu/drm/drm_gpusvm.c | 67 ++++++++++++++++++++++++------------ > 1 file changed, 45 insertions(+), 22 deletions(-) > > diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c > index fcfe635bc195..507ef6f0a60e 100644 > --- a/drivers/gpu/drm/drm_gpusvm.c > +++ b/drivers/gpu/drm/drm_gpusvm.c > @@ -1442,6 +1442,50 @@ static bool drm_gpusvm_pages_valid_unlocked(struct > drm_gpusvm *gpusvm, > return pages_valid; > } > > +/** > + * drm_gpusvm_hmm_fault() - Run the shared HMM fault for a CPU range > + * @gpusvm: Pointer to the GPU SVM structure > + * @mm: The mm corresponding to the CPU range > + * @hmm_range: The hmm_range to fault. > + * @pfns: The pfn array to populate (size @npages) > + * @timeout: jiffies deadline for the -EBUSY retry loop > + * > + * Fault the CPU pages of the range into @pfns. This is the MM level step. > + * > + * Return: 0 on success, negative error code on failure. > + */ > +static int drm_gpusvm_hmm_fault(struct drm_gpusvm *gpusvm, > + struct mm_struct *mm, > + struct hmm_range *hmm_range, > + unsigned long *pfns, > + unsigned long timeout) > +{ > + int err; > + > + if (!mmget_not_zero(mm)) > + return -EFAULT; > + > + hmm_range->hmm_pfns = pfns; > + while (true) { > + mmap_read_lock(mm); > + err = hmm_range_fault(hmm_range); > + mmap_read_unlock(mm); > + > + if (err == -EBUSY) { > + if (time_after(jiffies, timeout)) > + break; > + > + hmm_range->notifier_seq = > + mmu_interval_read_begin(hmm_range->notifier); > + continue; > + } > + break; > + } > + mmput(mm); > + > + return err; > +} > + > /** > * drm_gpusvm_get_pages() - Get pages and populate GPU SVM pages struct > * @gpusvm: Pointer to the GPU SVM structure > @@ -1503,28 +1547,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, > if (!pfns) > return -ENOMEM; > > - if (!mmget_not_zero(mm)) { > - err = -EFAULT; > - goto err_free; > - } > - > - hmm_range.hmm_pfns = pfns; > - while (true) { > - mmap_read_lock(mm); > - err = hmm_range_fault(&hmm_range); > - mmap_read_unlock(mm); > - > - if (err == -EBUSY) { > - if (time_after(jiffies, timeout)) > - break; > - > - hmm_range.notifier_seq = > - mmu_interval_read_begin(notifier); > - continue; > - } > - break; > - } > - mmput(mm); > + err = drm_gpusvm_hmm_fault(gpusvm, mm, &hmm_range, pfns, timeout); > if (err) > goto err_free; > > -- > 2.34.1 >
