From: Rik van Riel <riel@surriel.com>
To: linux-kernel@vger.kernel.org, Andrew Morton <akpm@linux-foundation.org>
Cc: kernel-team@meta.com, Rik van Riel <riel@surriel.com>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
Vlastimil Babka <vbabka@kernel.org>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>,
linux-mm@kvack.org
Subject: [PATCH v3 0/6] mm: access remote process memory under the per-VMA lock
Date: Fri, 17 Jul 2026 13:00:30 -0400 [thread overview]
Message-ID: <20260717170036.743149-1-riel@surriel.com> (raw)
__access_remote_vm() holds mmap_read_lock() for the whole transfer. On
large machines with large multi-threaded applications, the mmap_lock
is often contended due to mixed accesses from readers and writers, like
mmap and munmap. When a lock holder gets stuck, system monitoring software
can get stuck behind that, resulting in a failure to log that the system
is in trouble.
Take the per-VMA lock in __access_remote_vm() when the access falls
entirely within a single VMA. Fall back to the mmap lock when the access
crosses a VMA boundary, or when the page cannot be reached under the
per-VMA lock: a dropped fault, a userfaultfd VMA, a hard error, or memory
with no struct page that has to go through vma->vm_ops->access().
The bulk of the work is a new gup helper. __access_remote_vm() needs a
single page from a VMA it has already looked up and locked, faulting it in
when necessary, under either lock.
get_user_pages_remote() does not fit: it hard codes the mmap lock and
re-derives the VMA. get_user_page_vma() walks the page tables, faults a
missing page in, and returns it with a reference and the caller's lock
still held.
The per-VMA path also closes a pre-existing gap. A COWed page in a
VM_IO/VM_PFNMAP VMA has a struct page, but the old code routed it to
->access(), where generic_access_phys() ioremaps the PFN and ioremap of RAM
is rejected, so the read came up short.
get_user_page_vma() now returns that page normally. Raw PFNs with no struct
page still reach ->access() under the mmap lock, as before.
The series is arranged as:
1-2: untag the remote address in the VMA lookup without the mmap lock,
on x86 and riscv.
3: rename get_user_page_vma_remote() to get_user_page_lookup_vma().
4: add get_user_page_vma().
5: switch __access_remote_vm() to the per-VMA lock.
6: add selftest coverage.
Changes since v2 [1]. The per-VMA fast path is reworked to build on the GUP
lookup+fault path instead of a custom walker, per David Hildenbrand's
and Lorenzo Stoakes' review, and now faults pages in rather than only
reading resident ones.
- Drop the folio_walk_start(FW_VMA_LOCKED) walk. Add get_user_page_vma()
in mm/gup.c (patch 4): a trimmed __get_user_pages() that walks with
follow_page_mask(), faults in with faultin_page(), and returns the page
with the caller's lock held. Safe under the per-VMA lock because page
tables are RCU-freed, so interrupts need not be disabled. (David)
- Fault pages in on the fast path. v2 fell back to the mmap lock for any
not-present page; now it falls back only on -EAGAIN. (David)
- Turn the v2 READ_ONCE/WRITE_ONCE untag_mask change into an
untagged_addr_remote_unlocked() helper (patch 1), and add the riscv
pointer-masking equivalent (patch 2), which v2 did not cover.
- Read COWed pages in VM_IO/VM_PFNMAP VMAs; raw PFNs still fall back to
->access() under the mmap lock.
- Add the get_user_page_lookup_vma() rename (patch 3) and selftest
coverage for the struct-page and raw-PFN paths (patch 6).
[1] https://lore.kernel.org/all/20260625015053.2445008-1-riel@surriel.com/
Rik van Riel (6):
x86/mm: add untagged_addr_remote_unlocked()
riscv/mm: add untagged_addr_remote_unlocked()
mm: rename get_user_page_vma_remote() to get_user_page_lookup_vma()
mm/gup: add get_user_page_vma() to fault in a page under a held lock
mm: use per-VMA lock in __access_remote_vm() for single-VMA accesses
selftests/mm: cover /proc/pid/mem access to VM_PFNMAP memory
arch/arm64/kernel/mte.c | 2 +-
arch/riscv/include/asm/mmu_context.h | 4 +-
arch/riscv/include/asm/uaccess.h | 10 +-
arch/riscv/kernel/process.c | 12 +-
arch/x86/include/asm/mmu_context.h | 6 +-
arch/x86/include/asm/uaccess_64.h | 14 ++-
arch/x86/kernel/process_64.c | 4 +-
arch/x86/kernel/uprobes.c | 2 +-
include/linux/mm.h | 2 +-
include/linux/uaccess.h | 7 ++
mm/gup.c | 156 ++++++++++++++++++++++----
mm/internal.h | 7 +-
mm/memory.c | 171 ++++++++++++++++++++-------
mm/rmap.c | 2 +-
tools/testing/selftests/mm/pfnmap.c | 66 +++++++++++
15 files changed, 375 insertions(+), 90 deletions(-)
base-commit: 0f26556c5eeea62cc934fa8938b148aa5844a6b6
--
2.47.0
next reply other threads:[~2026-07-17 17:01 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-17 17:00 Rik van Riel [this message]
2026-07-17 17:00 ` [PATCH RFC v3 1/6] x86/mm: add untagged_addr_remote_unlocked() Rik van Riel
2026-07-20 11:12 ` Usama Arif
2026-07-17 17:00 ` [PATCH RFC v3 2/6] riscv/mm: " Rik van Riel
2026-07-20 11:57 ` Usama Arif
2026-07-20 15:08 ` Rik van Riel
2026-07-20 16:46 ` Usama Arif
2026-07-20 17:34 ` Rik van Riel
2026-07-20 18:46 ` Usama Arif
2026-07-20 19:21 ` Rik van Riel
2026-07-20 19:39 ` Usama Arif
2026-07-17 17:00 ` [PATCH RFC v3 3/6] mm: rename get_user_page_vma_remote() to get_user_page_lookup_vma() Rik van Riel
2026-07-20 12:00 ` Usama Arif
2026-07-17 17:00 ` [PATCH RFC v3 4/6] mm/gup: add get_user_page_vma() to fault in a page under a held lock Rik van Riel
2026-07-20 12:35 ` Usama Arif
2026-07-20 15:24 ` Rik van Riel
2026-07-17 17:00 ` [PATCH RFC v3 5/6] mm: use per-VMA lock in __access_remote_vm() for single-VMA accesses Rik van Riel
2026-07-17 17:00 ` [PATCH RFC v3 6/6] selftests/mm: cover /proc/pid/mem access to VM_PFNMAP memory Rik van Riel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260717170036.743149-1-riel@surriel.com \
--to=riel@surriel.com \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=kernel-team@meta.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=rppt@kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox