No upstream commit exists for this commit. The issue was introduced with backporting upstream commit 091c1dd2d4df ("mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a MM"). The backport incorrectly added unlock logic to a path where mmap_lock was provided by external context in do_migrate_pages(), creating lock imbalance when no VMAs are found. This fixes the report: WARNING: bad unlock balance detected! 6.6.79 #1 Not tainted ------------------------------------- repro/9655 is trying to release lock (&mm->mmap_lock) at: [<ffffffff81daa36f>] mmap_read_unlock include/linux/mmap_lock.h:173 [inline] [<ffffffff81daa36f>] do_migrate_pages+0x59f/0x700 mm/mempolicy.c:1196 but there are no more locks to release! other info that might help us debug this: no locks held by repro/9655. stack backtrace: CPU: 1 PID: 9655 Comm: a Not tainted 6.6.79 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd5/0x1b0 lib/dump_stack.c:106 __lock_release kernel/locking/lockdep.c:5431 [inline] lock_release+0x4b1/0x680 kernel/locking/lockdep.c:5774 up_read+0x12/0x20 kernel/locking/rwsem.c:1615 mmap_read_unlock include/linux/mmap_lock.h:173 [inline] do_migrate_pages+0x59f/0x700 mm/mempolicy.c:1196 kernel_migrate_pages+0x59b/0x780 mm/mempolicy.c:1665 __do_sys_migrate_pages mm/mempolicy.c:1684 [inline] __se_sys_migrate_pages mm/mempolicy.c:1680 [inline] __x64_sys_migrate_pages+0x92/0xf0 mm/mempolicy.c:1680 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x34/0xb0 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x68/0xd2 Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: a13b2b9b0b0b ("mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a MM") Signed-off-by: Alexey Panov <apanov@xxxxxxxxxxxxx> --- v2: Clarify mmap_lock context in commit description. Fix braces for a single statement block. Add empty line after VM_BUG_ON to look more consistent with upstream. mm/mempolicy.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 94c74c594d10..d2855507d2e9 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1070,11 +1070,10 @@ static long migrate_to_node(struct mm_struct *mm, int source, int dest, node_set(source, nmask); VM_BUG_ON(!(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))); + vma = find_vma(mm, 0); - if (unlikely(!vma)) { - mmap_read_unlock(mm); + if (unlikely(!vma)) return 0; - } /* * This does not migrate the range, but isolates all pages that -- 2.30.2