[PATCH bpf-next 2/9] uprobes: Don't run exit_mmap() under dup_mmap_sem
From: Alexei Starovoitov
Date: Wed Oct 21 2026 - 21:57:52 EST
From: Alexei Starovoitov <ast@xxxxxxxxxx>
build_map_info() takes mm_users of every mm that maps the file and
register_for_each_vma() drops it after the visit. When the process has
exited meanwhile it's the last mmput(), and exit_mmap() of a large mm runs
with dup_mmap_sem held for writing. Every fork() in the system waits for
it. Use mmput_async().
Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx>
---
kernel/events/uprobes.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 7709ea882477..6792004be6fa 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1250,7 +1250,7 @@ build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
prev = curr;
while (curr) {
- mmput(curr->mm);
+ mmput_async(curr->mm);
curr = curr->next;
}
@@ -1324,7 +1324,8 @@ register_for_each_vma(struct uprobe *uprobe, struct uprobe_consumer *new)
unlock:
mmap_write_unlock(mm);
free:
- mmput(mm);
+ /* exit_mmap() of the last user must not run under dup_mmap_sem */
+ mmput_async(mm);
info = free_map_info(info);
}
out:
--
2.55.0