Re: [PATCH v10 0/8] mm/hmm: Add mmap lock-drop support for userfaultfd-backed mappings
Andrew Morton <[email protected]> Wed, 22 Jul 2026 15:48:17 -0700
| Newsgroups | org.freedesktop.lists.nouveau,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-doc,org.kernel.vger.linux-hyperv,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kernel.vger.linux-rdma,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
On Wed, 22 Jul 2026 14:44:22 -0700 Stanislav Kinsburskii <[email protected]> wrote: > This series extends the HMM framework to support userfaultfd-backed memory > by allowing the mmap read lock to be dropped during hmm_range_fault(). Thanks, I've updated mm.git's mm-unstable branch to this version. Sashiko pointed at a few things, some pre-existing. The jiffies race in [8/8] looks legit. https://sashiko.dev/#/patchset/[email protected] > Changes in v10: > - Included contended mmap_lock acquisition in the > hmm_range_fault_unlocked_timeout() retry budget. > - Dropped the redundant top-level fatal_signal_pending() check in the HMM > unlocked retry loop; mmap_read_lock_killable() now covers that path. > - Restored the absolute outer timeout in drm_gpusvm_get_pages(), since it can > run from GPU page-fault workers and must not rely on the worker task’s fatal > signal state to stop invalidation retries. Here's how v10 altered mm.git: drivers/gpu/drm/drm_gpusvm.c | 11 +++++++++-- mm/hmm.c | 29 +++++++++++++---------------- 2 files changed, 22 insertions(+), 18 deletions(-) --- a/drivers/gpu/drm/drm_gpusvm.c~b +++ a/drivers/gpu/drm/drm_gpusvm.c @@ -1405,7 +1405,9 @@ int drm_gpusvm_get_pages(struct drm_gpus .dev_private_owner = ctx->device_private_page_owner, }; void *zdd; - unsigned long timeout = msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); + unsigned long timeout = + jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); + unsigned long remaining; unsigned long i, j; unsigned long npages = npages_in_range(pages_start, pages_end); unsigned long num_dma_mapped; @@ -1420,6 +1422,11 @@ int drm_gpusvm_get_pages(struct drm_gpus struct dma_iova_state *state = &svm_pages->state; retry: + if (time_after_eq(jiffies, timeout)) + return -EBUSY; + + remaining = timeout - jiffies; + hmm_range.notifier_seq = mmu_interval_read_begin(notifier); if (drm_gpusvm_pages_valid_unlocked(gpusvm, svm_pages)) goto set_seqno; @@ -1434,7 +1441,7 @@ retry: } hmm_range.hmm_pfns = pfns; - err = hmm_range_fault_unlocked_timeout(&hmm_range, timeout); + err = hmm_range_fault_unlocked_timeout(&hmm_range, remaining); mmput(mm); if (err) goto err_free; --- a/mm/hmm.c~b +++ a/mm/hmm.c @@ -790,22 +790,14 @@ int hmm_range_fault_unlocked_timeout(str int ret; do { - if (fatal_signal_pending(current)) - return -EINTR; - - if (timeout) { - /* - * If the previous fault dropped mmap_lock, then the fault - * handler made progress. Restart the retry timeout in that - * case, but keep the existing deadline for ordinary -EBUSY - * retries. - */ - if (!locked) - deadline = jiffies + timeout; - - if (time_after(jiffies, deadline)) - return -EBUSY; - } + /* + * If the previous fault dropped mmap_lock, then the fault + * handler made progress. Restart the retry timeout in that + * case, but keep the existing deadline for ordinary -EBUSY + * retries. + */ + if (timeout && !locked) + deadline = jiffies + timeout; range->notifier_seq = mmu_interval_read_begin(range->notifier); @@ -814,6 +806,11 @@ int hmm_range_fault_unlocked_timeout(str if (ret) return ret; + if (timeout && time_after(jiffies, deadline)) { + mmap_read_unlock(mm); + return -EBUSY; + } + locked = true; ret = hmm_range_fault_locked(range, &locked); if (locked) _