v4
2026-07-25
per-VMA锁优化远程内存访问 · v4
使用per-VMA锁优化__access_remote_vm(),减少mmap_lock竞争并批量处理大folio。
原始补丁链接
子 Patch(12)
1/12
x86/mm: add untagged_addr_remote_unlocked()
__access_remote_vm() reads another process’s memory under the mmap lock. On large machines running big multi-threaded applications, that lock is contended between readers and writers: an mmap() or mun
2/12
riscv/mm: add untagged_addr_remote_unlocked()
__access_remote_vm() reads another task’s memory under the mmap lock. That lock is contended on large multi-threaded workloads, where an mmap() or munmap() stalls readers like /proc/PID/cmdline or pro
3/12
mm: rename get_user_page_vma_remote() to get_user_page_lookup_vma()
get_user_page_vma_remote() faults in the page at @addr in a remote mm and also looks up the VMA that covers it, handing both back to the caller. This cleans up the namespace for adding a get_user_pag
4/12
mm/gup: let check_vma_flags() ignore selected VMA flags
check_vma_flags() rejects a VMA whose flags gup cannot handle. A caller that wants to reach a COWed page in a VM_IO or VM_PFNMAP VMA, where that page does have a struct page, cannot express the except
5/12
mm/gup: add get_user_page_vma() to fault in a page under a held lock
__access_remote_vm() needs a single page from a VMA it has already looked up and locked, faulting it in when necessary, under either the mmap lock or the per-VMA lock. get_user_pages_remote() does not
6/12
mm: use per-VMA lock in __access_remote_vm() for single-VMA accesses
__access_remote_vm() holds mmap_read_lock() for the whole transfer. On large machines running big multi-threaded applications, that lock is contended between readers and writers: an mmap() or munmap()
7/12
mm: read remote strings under the per-VMA lock
[mm: read remote strings under the per-VMA lock] __copy_remote_vm_str() reads another process’s memory under the mmap read lock for the whole copy, and looks the VMA up again for every page through ge
8/12
selftests/mm: cover /proc/pid/mem access to VM_PFNMAP memory
Reading a VM_PFNMAP mapping through /proc/pid/mem exercises __access_remote_vm() two ways: a COWed page has a struct page and is returned by get_user_page_vma(), while a raw PFN has none and is reache
9/12
mm/gup: build get_user_page_lookup_vma() on get_user_page_vma()
get_user_page_lookup_vma() faults in one page of a remote mm and returns it together with the VMA that covers it. It open-codes that with get_user_pages_remote() followed by vma_lookup(), duplicating
10/12
mm/gup: pass an end address to follow_page_mask() and return a page count
follow_page_mask() reports how many pages the returned page covers with a page_mask: a bitmask of the enclosing naturally-aligned huge page. Callers turn that into a stride, which assumes the run is a
11/12
mm/gup: batch contiguous PTE-mapped large folios in follow_page_mask()
follow_page_mask() returns one page per call for a PTE-mapped large folio, so __get_user_pages() re-walks the page tables for every page of an mTHP even though the folio maps a contiguous run. The hug
12/12
selftests/mm: add a slow-GUP content and COW test for mTHP
follow_page_mask() now batches a PTE-mapped large folio (mTHP) into one contiguous run for the slow get_user_pages() path. A mis-batched run would hand back the wrong pages or a stale COW copy, which