Re: [PATCH bpf-next 5/9] uprobes: Don't sleep on mmap_lock under dup_mmap_sem
flat view
From: bot+bpf-ci@kernel.org
Date: 2026-10-22 02:37:29
Also in:
bpf, linux-mm, linux-perf-users, lkml
uprobes: Don't sleep on mmap_lock under dup_mmap_sem
TL;DR: Question, possibly not a bug: uprobe_dup_mmap() edits oldmm page tables
inside dup_mmap() before vma_start_write(), so it may race with per-VMA read
lockers (page fault, MADV_DONTNEED); the review suspects it is safe.
quoted hunk ↗ jump to hunk
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c
[ ... ]
quoted hunk ↗ jump to hunk
void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) { + struct uprobe_walk *walk; + struct map_info *info; + + list_for_each_entry(walk, &uprobe_walks, list) { + /* + * fork() that is being killed fails in copy_process(). + * There will be no child. Leave oldmm to the walk. + */ + if (fatal_signal_pending(current)) + break; + for (info = walk->busy; info; info = info->next) + if (info->mm == oldmm) + register_one_mm(walk, info, true); + } +
A subsystem pattern flags this call as potentially concerning, so this may not be a bug. uprobe_dup_mmap() is called from dup_mmap() with mmap_write_lock_killable() held on oldmm, and before the copy loop reaches vma_start_write_killable() on each vma: dup_mmap() mmap_write_lock_killable(oldmm) uprobe_dup_mmap(oldmm, mm) register_one_mm(walk, info, true) install_breakpoint() / remove_breakpoint() set_swbp() / set_orig_insn() uprobe_write() get_user_pages_remote() folio_walk_start() + __uprobe_write() collapse_pte_mapped_thp() (unregister path) try_collapse_pte_mapped_thp() pmdp_collapse_flush() + pte_free_defer() ... vma_start_write_killable(mpnt) The guide for the VMA locking code says to report functions that hold mmap_write_lock and access page tables or PTE pages before calling vma_start_write(vma), because other threads of the forking process may still hold per-VMA read locks on the same vma, for example in a page fault or in MADV_DONTNEED with CONFIG_PT_RECLAIM. Can uprobe_write() and collapse_pte_mapped_thp() run against oldmm here while another thread of the forking process holds a per-VMA read lock on the same vma? For context, the existing register_for_each_vma() -> register_one_mm() walk already did this with only mmap_write_lock held. What this patch adds is a second caller of that code inside dup_mmap(), which did no page table access on oldmm before vma_start_write(). On the other side, uprobe_write() takes the page table lock through folio_walk_start() and retries when fw.page does not match the expected page, and try_collapse_pte_mapped_thp() re-checks pmd_same() under the locks before pmdp_collapse_flush(). khugepaged's retract_page_tables() also retracts page tables without mmap_lock at all. So it may be that this access is safe without the per-VMA write lock. Could you confirm whether the vma_start_write() rule is meant to apply to the uprobe_write() path called from uprobe_dup_mmap()? --- AI reviewed your patch. Please fix the bug or email reply why it's not a bug. See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md CI run summary: https://github.com/kernel-patches/bpf/actions/runs/39710454342