Re: [RFC PATCH v3] mm: retry page faults under per-VMA lock when mmap_lock is not required

From: Hongru Zhang

Date: Sun Jul 12 2026 - 09:28:48 EST


> On Tue, Jul 07, 2026 at 05:52:31PM +0100, Lorenzo Stoakes wrote:
> > +cc Vlata, the only one from the MEMORY MAPPING - LOCKING people excluded,
> > and Willy as he's been heavily involved. But see below you need to cc- way
> > more.
>
> Ugh, I hadn't seen this.
>
> No.
>
> I've been looking into this problem, and as usual it has turned into a
> yak-shaving exercise. I think I'm five yaks deep at this point:
>
> - Need to start by simplifying filemap_fault
> https://lore.kernel.org/linux-mm/20260625195040.2508362-1-willy@xxxxxxxxxxxxx/

Hi Matthew,

Thanks for looking at this.

I understand your concern about adding more complexity to an already
complicated fault path.

However, I tested the RFC patch [1] on Android workloads and observed
lock-wait regressions. The common pattern is that filemap_fault() can perform
file-backed I/O while holding either mmap_lock or a per-VMA lock. The traces
show three representative classes of lock-wait regressions: GUP faults,
kernel uaccess faults, and per-VMA-lock faults blocking fork / copy_mm().

1) GUP faults under mmap_lock

APP: com.xs.fm.lite
lock type: mmap_lock
holder: Thread-77
faulted file: libbytehook.so
lock-held filemap fault time: 95.606ms
blocked writer: NetDownload#15 (blocked 218.971ms)

Holder stack:
filemap_fault+0x0
__do_fault+0xdc
do_pte_missing+0x2c8
handle_mm_fault+0x4c8
__get_user_pages+0x618
__gup_longterm_locked+0xac
pin_user_pages_remote+0x88
process_vm_rw+0x2cc
__arm64_sys_process_vm_readv+0x28
invoke_syscall+0x58
el0_svc_common+0x80
do_el0_svc+0x1c
el0_svc+0x48
el0t_64_sync_handler+0x70
el0t_64_sync+0x1bc

Blocked writer stack:
vm_mmap_pgoff+0x168
ksys_mmap_pgoff+0xa4
__arm64_sys_mmap+0x34
invoke_syscall+0x58
el0_svc_common+0x80
do_el0_svc+0x1c
el0_svc+0x48
el0t_64_sync_handler+0x70
el0t_64_sync+0x1bc

2) kernel uaccess faults under mmap_lock

APP: com.xingin.xhs
lock type: mmap_lock
holder: Thread-2531
faulted file: libtiny.so
lock-held filemap fault time: 172.375ms
blocked writer count: 5
writer wait range: 152.766ms - 172.006ms
representative blocked writer: com.xingin.xhs (main thread, blocked 172.006ms)

Holder stack:
filemap_fault+0x0
__do_fault+0xdc
do_pte_missing+0x2c8
handle_mm_fault+0x4c8
do_page_fault+0x39c
do_translation_fault+0x4c
do_mem_abort+0x54
el1_abort+0x3c
el1h_64_sync_handler+0x80
el1h_64_sync+0x7c
__arch_copy_from_user+0x1b4
copy_page_from_iter+0xd0
pipe_write+0x1ec
vfs_write+0x368
ksys_write+0x78
__arm64_sys_write+0x1c
invoke_syscall+0x58
el0_svc_common+0x80
do_el0_svc+0x1c
el0_svc+0x48
el0t_64_sync_handler+0x70
el0t_64_sync+0x1bc

Blocked writer stack:
vm_mmap_pgoff+0x168
ksys_mmap_pgoff+0xa4
__arm64_sys_mmap+0x34
invoke_syscall+0x58
el0_svc_common+0x80
do_el0_svc+0x1c
el0_svc+0x48
el0t_64_sync_handler+0x70
el0t_64_sync+0x1bc

3) filemap faults under per-VMA lock blocking fork / copy_mm()

Other testing also reported similar per-VMA-lock blocking data [2], where
filemap faults under a VMA read lock can block fork / copy_mm(). One example
from my trace is:

APP: com.xingin.xhs
lock type: per-VMA lock
holder: xylog_thread_po
faulted file: 2026-07-07-11-51-46.203.log
lock-held filemap fault time: 10.518ms
blocked writer: com.xingin.xhs (blocked 1.583ms)

Holder stack:
filemap_fault+0x0
__do_fault+0xdc
do_pte_missing+0x2c8
handle_mm_fault+0x4c8
do_page_fault+0x30c
do_translation_fault+0x4c
do_mem_abort+0x54
el0_da+0x54
el0t_64_sync_handler+0x50
el0t_64_sync+0x1bc

Blocked writer stack:
copy_mm+0x2a4
copy_process+0x4ec
kernel_clone+0xb0
__arm64_sys_clone+0x60
invoke_syscall+0x58
el0_svc_common+0x80
do_el0_svc+0x1c
el0_svc+0x48
el0t_64_sync_handler+0x70
el0t_64_sync+0x1bc

> - To do that, need to improve how we handle unlocking for faults
> (not posted because ...)
> - To do that, need to redo the hugetlb fault handler
> (not posted because ...)
> - To do that, need to get Jane's series landed
> https://lore.kernel.org/linux-mm/20260617172534.1740152-1-jane.chu@xxxxxxxxxx/
> https://lore.kernel.org/linux-mm/20260709184740.1286561-1-willy@xxxxxxxxxxxxx/
> - To do that, need to redo how we handle hwpoison of hugetlb code
> https://lore.kernel.org/linux-mm/alEpBqExnyvBnnxi@xxxxxxxxxxxxxxxxxxxx/
>
> So yeah, I'm not impressed by the approach taken in this patch which
> adds more complexity on top of a system that's creaking at the seams
> with existing complexity.

[1] https://lore.kernel.org/linux-mm/20260622192114.1147198-1-willy@xxxxxxxxxxxxx/
[2] https://lore.kernel.org/linux-mm/CAGsJ_4xC5LdhuoWV1=tK-RZ5rkjc8aOKOkmb1L_8BG_3gtJhDg@xxxxxxxxxxxxxx/