Documentation/mm/hmm.rst | 76 +++++++-- drivers/accel/amdxdna/aie2_ctx.c | 17 -- drivers/gpu/drm/drm_gpusvm.c | 52 +----- drivers/gpu/drm/nouveau/nouveau_svm.c | 12 - drivers/hv/mshv_regions.c | 54 +------ drivers/infiniband/core/umem_odp.c | 18 +- include/linux/hmm.h | 2 lib/test_hmm.c | 107 +++++++++++++ lib/test_hmm_uapi.h | 1 mm/hmm.c | 259 +++++++++++++++++++++++++------- tools/testing/selftests/mm/hmm-tests.c | 150 +++++++++++++++++++ 11 files changed, 541 insertions(+), 207 deletions(-)
This series extends the HMM framework to support userfaultfd-backed memory
by allowing the mmap read lock to be dropped during hmm_range_fault().
Some page fault handlers — most notably userfaultfd — require the mmap lock
to be released so that userspace can resolve the fault. The current HMM
interface never sets FAULT_FLAG_ALLOW_RETRY, making it impossible to fault
in pages from userfaultfd-registered regions.
This series follows the established int *locked pattern from
get_user_pages_remote() in mm/gup.c. A new helper function,
hmm_range_fault_locked(), accepts an int *locked parameter. When the
mmap lock is dropped during fault resolution (VM_FAULT_RETRY or
VM_FAULT_COMPLETED), the function returns 0 with *locked = 0, signalling
the caller to restart its walk. The existing hmm_range_fault() is
refactored into a thin wrapper that passes NULL, preserving current
behavior for all existing callers.
Possible approaches to lift this limitation are documented in
Documentation/mm/hmm.rst.
Changes in v8:
- Make hmm_range_fault_unlocked_timeout() the primary documented HMM
range-fault API, and move hmm_range_fault() into the “use only if the
caller really must hold mmap_lock” category.
- Clarify that the timeout is a retry budget for repeated mmu-notifier
invalidation retries. HMM does not interrupt an in-progress page fault
when the timeout expires.
- Restart the retry timeout only when handle_mm_fault() dropped
mmap_lock, because that indicates a lock-dropping fault handler such as
userfaultfd made progress. Ordinary -EBUSY retries keep the existing
deadline.
- Remove the attempted timeout selftest. The remaining selftest covers the
intended userfaultfd path by resolving missing-page faults through
HMM_DMIRROR_READ_UNLOCKED and hmm_range_fault_unlocked_timeout(..., 0).
Changes in v7:
- Replaced the unlocked HMM API with
hmm_range_fault_unlocked_timeout(). The helper now takes a timeout in
jiffies, with 0 meaning retry indefinitely.
- Moved -EBUSY retry handling into the HMM helper for the unlocked path.
The helper refreshes range->notifier_seq internally before each retry.
- Switched the unlocked path to mmap_read_lock_killable() and return
-EINTR if mmap lock acquisition is interrupted or a fatal signal is
pending during retry handling.
- Removed the redundant non-timeout hmm_range_fault_unlocked() interface.
- Updated Documentation/mm/hmm.rst and kernel-doc to describe the timeout API
and the intended caller pattern.
- Updated the HMM selftests to use hmm_range_fault_unlocked_timeout()
only, including coverage for the finite-timeout path.
- Added in-tree users of the new helper:
- mshv
- nouveau
- RDMA/umem
- amdxdna
- drm/gpusvm
- Preserved each converted driver’s existing timeout convention:
- unbounded retry where the old code retried indefinitely,
- HMM_RANGE_DEFAULT_TIMEOUT where the old code used that budget,
- existing driver-specific timeout return values such as -ETIME.
- Used max_t(long, timeout - jiffies, 1) when passing remaining time from
absolute jiffies deadlines to avoid unsigned underflow while keeping a
minimum one-jiffy retry window.
- Left callers on hmm_range_fault() when they already need to hold
mmap_lock across surrounding work, such as drm_gpusvm_check_pages().
Changes in v6:
- Reworked the new API from the external int *locked pattern to
hmm_range_fault_unlocked(), which owns mmap_read_lock() internally.
- Changed the dropped-lock contract: hmm_range_fault_unlocked() now returns
-EBUSY when the mmap lock is dropped, and callers restart with a fresh
mmu_interval_read_begin() sequence.
- Kept hmm_range_fault() as the locked variant for existing users, preserving
its caller-held mmap lock contract.
- Added an in-tree user by converting the MSHV region fault path to
hmm_range_fault_unlocked().
- Updated Documentation/mm/hmm.rst and kernel-doc to describe the unlocked
helper and retry pattern.
- Updated commit messages to match the new API and return semantics.
- Kept the userfaultfd HMM selftest using the test_hmm unlocked read ioctl
path.
Changes in v5:
- Rework hmm_range_fault_unlockable() retry handling to retry
VM_FAULT_RETRY internally with FAULT_FLAG_TRIED set, matching the
fixup_user_fault() pattern and avoiding repeated first-retry lock drops.
- Distinguish VM_FAULT_RETRY from VM_FAULT_COMPLETED: retry faults now
reacquire the mmap lock internally, while completed faults return to the
caller with *locked = 0 so the caller can restart with a fresh notifier
sequence.
- Document the two *locked return states, including the -EINTR case when a
fatal signal is pending after the mmap lock has already been dropped.
- Update comments around HMM_FAULT_UNLOCKED and the HMM fault loop to match
the current hmm_range_fault_unlockable() implementation.
Changes in v4:
- Rebased on 7.2-rc1
Changes in v3:
- Return -EFAULT from dmirror_fault_unlockable() when the mirrored mm can
no longer be pinned.
- Add an eventfd stop signal for the userfaultfd handler thread to avoid
waiting for the poll timeout on successful test completion.
Changes in v2:
- Split into a preparatory refactor (new patch 1) that moves
handle_mm_fault() out of the walk callbacks, plus a smaller feature
patch on top. Suggested by David Hildenbrand.
- Hugetlb regions are now supported on the unlockable path; the v1
-EFAULT short-circuit and the hugetlb_vma_lock_read drop/retake
dance are gone.
- Distinct internal sentinels for "needs fault" (HMM_FAULT_PENDING)
and "lock dropped" (HMM_FAULT_UNLOCKED).
- Outer loop now re-walks after a successful internal fault so the
faulted pfns end up in range->hmm_pfns.
- Kernel-doc on hmm_range_fault_unlockable() and the
Documentation/mm/hmm.rst example match the implementation.
- Dropped the mshv driver conversion (v1 patch 2); will post
separately.
- Selftest converted to drive the path through test_hmm with a
userfaultfd handler (new HMM_DMIRROR_READ_UNLOCKABLE ioctl).
---
Stanislav Kinsburskii (8):
mm/hmm: move page fault handling out of walk callbacks
mm/hmm: add hmm_range_fault_unlocked_timeout() for mmap lock-drop support
selftests/mm: add HMM test for mmap lock-dropping faults
mshv: Use hmm_range_fault_unlocked_timeout() for region faults
drm/nouveau: Use hmm_range_fault_unlocked_timeout() for SVM faults
RDMA/umem: Use hmm_range_fault_unlocked_timeout() for ODP faults
accel/amdxdna: Use hmm_range_fault_unlocked_timeout() for range population
drm/gpusvm: Use hmm_range_fault_unlocked_timeout() for range faults
Documentation/mm/hmm.rst | 76 +++++++--
drivers/accel/amdxdna/aie2_ctx.c | 17 --
drivers/gpu/drm/drm_gpusvm.c | 52 +-----
drivers/gpu/drm/nouveau/nouveau_svm.c | 12 -
drivers/hv/mshv_regions.c | 54 +------
drivers/infiniband/core/umem_odp.c | 18 +-
include/linux/hmm.h | 2
lib/test_hmm.c | 107 +++++++++++++
lib/test_hmm_uapi.h | 1
mm/hmm.c | 259 +++++++++++++++++++++++++-------
tools/testing/selftests/mm/hmm-tests.c | 150 +++++++++++++++++++
11 files changed, 541 insertions(+), 207 deletions(-)
On Fri, 10 Jul 2026 14:26:20 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> 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. This seems fairly mature and mostly-reviewed so I'll give it a spin in mm.git's mm-new branch. Unfortunately Sashiko wasn't able to apply this or v7. I'm not sure what base you were using. Hopefully there's a reason for a v9 so we can retry this. I have a few niggles, nothing major...
On Fri, Jul 10, 2026 at 03:11:51PM -0700, Andrew Morton wrote: > On Fri, 10 Jul 2026 14:26:20 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> 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. This seems fairly mature and mostly-reviewed so I'll give it a > spin in mm.git's mm-new branch. > > Unfortunately Sashiko wasn't able to apply this or v7. I'm not sure > what base you were using. Hopefully there's a reason for a v9 so we > can retry this. > I rebased this series on top of mm-new right before sending it out. Should I have used a different branch? Thanks, Stanislav > I have a few niggles, nothing major...
On Fri, 10 Jul 2026 20:22:33 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote: > On Fri, Jul 10, 2026 at 03:11:51PM -0700, Andrew Morton wrote: > > On Fri, 10 Jul 2026 14:26:20 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> 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. This seems fairly mature and mostly-reviewed so I'll give it a > > spin in mm.git's mm-new branch. > > > > Unfortunately Sashiko wasn't able to apply this or v7. I'm not sure > > what base you were using. Hopefully there's a reason for a v9 so we > > can retry this. > > > > I rebased this series on top of mm-new right before sending it out. > Should I have used a different branch? mm-new is good - Sashiko attempts that. But it's changing rapidly at this point in the development cycle.
On Fri, Jul 10, 2026 at 10:49:50PM -0700, Andrew Morton wrote: > On Fri, 10 Jul 2026 20:22:33 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote: > > > On Fri, Jul 10, 2026 at 03:11:51PM -0700, Andrew Morton wrote: > > > On Fri, 10 Jul 2026 14:26:20 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> 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. This seems fairly mature and mostly-reviewed so I'll give it a > > > spin in mm.git's mm-new branch. > > > > > > Unfortunately Sashiko wasn't able to apply this or v7. I'm not sure > > > what base you were using. Hopefully there's a reason for a v9 so we > > > can retry this. > > > > > > > I rebased this series on top of mm-new right before sending it out. > > Should I have used a different branch? > > mm-new is good - Sashiko attempts that. But it's changing rapidly at > this point in the development cycle. > I’d like to send another revision addressing a few comments and also replace the `max/max_t` check with something simpler. Which branch should I base it on so that Sashiko can apply it successfully? Or would it be better to send fixups against `mm-new`? Thanks, Stanislav
On Mon, 13 Jul 2026 13:57:55 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote: > > > I rebased this series on top of mm-new right before sending it out. > > > Should I have used a different branch? > > > > mm-new is good - Sashiko attempts that. But it's changing rapidly at > > this point in the development cycle. > > > > I’d like to send another revision addressing a few comments and also > replace the `max/max_t` check with something simpler. > > Which branch should I base it on so that Sashiko can apply it > successfully? mainline Linus would be safest. > Or would it be better to send fixups against `mm-new`? That should work as well, but it doesn't give us a Sashiko scan of the whole patchset.
On Mon, Jul 13, 2026 at 03:45:35PM -0700, Andrew Morton wrote: > On Mon, 13 Jul 2026 13:57:55 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote: > > > > > I rebased this series on top of mm-new right before sending it out. > > > > Should I have used a different branch? > > > > > > mm-new is good - Sashiko attempts that. But it's changing rapidly at > > > this point in the development cycle. > > > > > > > I’d like to send another revision addressing a few comments and also > > replace the `max/max_t` check with something simpler. > > > > Which branch should I base it on so that Sashiko can apply it > > successfully? > > mainline Linus would be safest. > Looks like linux-next/master has been updated with the v8 of the series. I have v9 with a few small fixes, but it is too late to send it out already? If it's not, then what should I base it on? Thanks, Stanislav > > Or would it be better to send fixups against `mm-new`? > > That should work as well, but it doesn't give us a Sashiko scan of the > whole patchset.
On Tue, 14 Jul 2026 09:09:51 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote: > On Mon, Jul 13, 2026 at 03:45:35PM -0700, Andrew Morton wrote: > > On Mon, 13 Jul 2026 13:57:55 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote: > > > > > > > I rebased this series on top of mm-new right before sending it out. > > > > > Should I have used a different branch? > > > > > > > > mm-new is good - Sashiko attempts that. But it's changing rapidly at > > > > this point in the development cycle. > > > > > > > > > > I’d like to send another revision addressing a few comments and also > > > replace the `max/max_t` check with something simpler. > > > > > > Which branch should I base it on so that Sashiko can apply it > > > successfully? > > > > mainline Linus would be safest. > > > > Looks like linux-next/master has been updated with the v8 of the series. That's because v8 is in mm.git's mm-unstable branch. > I have v9 with a few small fixes, but it is too late to send it out already? It's called "unstable" for a reason! Material in mm-unstable is still under review, test and the latest stages of development. Getting things finalized for movement into the non-rebasing mm-stable branch, then into mainline. So altering or replacing patchsets while they're in mm-unstable is perfectly OK and expected. > If it's not, then what should I base it on? Well it's a bit tricky to replace a series when it's in mm-unstable. One can do a git-checkout of the commit which precedes the v8 series. Or base on current Linus mainline, which usually works out. Sending little fixup patches against what's presently in mm-unstable also works. I'll queue each one immediately behind the patch which it alters then squash them into their parent patch before moving the series into mm-stable. A third alternative is for me to drop v8 from mm-unstable, then you wait until that has propagated onto the servers or into linux-next, then base on that. This approach is OK but I kinda unprefer it because there's a bit of latency and it makes it harder for me to prepare my "here's how v9 altered mm.git" summaries. Which would you prefer?
On Tue, Jul 14, 2026 at 10:57:51AM -0700, Andrew Morton wrote: > On Tue, 14 Jul 2026 09:09:51 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote: > > > On Mon, Jul 13, 2026 at 03:45:35PM -0700, Andrew Morton wrote: > > > On Mon, 13 Jul 2026 13:57:55 -0700 Stanislav Kinsburskii <skinsburskii@gmail.com> wrote: > > > > > > > > > I rebased this series on top of mm-new right before sending it out. > > > > > > Should I have used a different branch? > > > > > > > > > > mm-new is good - Sashiko attempts that. But it's changing rapidly at > > > > > this point in the development cycle. > > > > > > > > > > > > > I’d like to send another revision addressing a few comments and also > > > > replace the `max/max_t` check with something simpler. > > > > > > > > Which branch should I base it on so that Sashiko can apply it > > > > successfully? > > > > > > mainline Linus would be safest. > > > > > > > Looks like linux-next/master has been updated with the v8 of the series. > > That's because v8 is in mm.git's mm-unstable branch. > > > I have v9 with a few small fixes, but it is too late to send it out already? > > It's called "unstable" for a reason! Material in mm-unstable is still > under review, test and the latest stages of development. Getting > things finalized for movement into the non-rebasing mm-stable branch, > then into mainline. > > So altering or replacing patchsets while they're in mm-unstable is > perfectly OK and expected. > > > If it's not, then what should I base it on? > > Well it's a bit tricky to replace a series when it's in mm-unstable. > One can do a git-checkout of the commit which precedes the v8 series. > Or base on current Linus mainline, which usually works out. > > Sending little fixup patches against what's presently in mm-unstable > also works. I'll queue each one immediately behind the patch which it > alters then squash them into their parent patch before moving the series > into mm-stable. > > A third alternative is for me to drop v8 from mm-unstable, then you > wait until that has propagated onto the servers or into linux-next, > then base on that. This approach is OK but I kinda unprefer it because > there's a bit of latency and it makes it harder for me to prepare my > "here's how v9 altered mm.git" summaries. > > > Which would you prefer? Well, given that Sashiko didn’t pick up my series based on mm-new, I’d prefer to send a few follow-up patches in the hope that they will be reviewed in the context of the original series. Thanks, Stanislav
© 2016 - 2026 Red Hat, Inc.