Skip to content

Commit dd83609

Browse files
deepanshu406akpm00
authored andcommitted
hugetlbfs: skip VMAs without shareable locks in hugetlb_vmdelete_list
hugetlb_vmdelete_list() uses trylock to acquire VMA locks during truncate operations. As per the original design in commit 40549ba ("hugetlb: use new vma_lock for pmd sharing synchronization"), if the trylock fails or the VMA has no lock, it should skip that VMA. Any remaining mapped pages are handled by remove_inode_hugepages() which is called after hugetlb_vmdelete_list() and uses proper lock ordering to guarantee unmapping success. Currently, when hugetlb_vma_trylock_write() returns success (1) for VMAs without shareable locks, the code proceeds to call unmap_hugepage_range(). This causes assertion failures in huge_pmd_unshare() → hugetlb_vma_assert_locked() because no lock is actually held: WARNING: CPU: 1 PID: 6594 Comm: syz.0.28 Not tainted Call Trace: hugetlb_vma_assert_locked+0x1dd/0x250 huge_pmd_unshare+0x2c8/0x540 __unmap_hugepage_range+0x6e3/0x1aa0 unmap_hugepage_range+0x32e/0x410 hugetlb_vmdelete_list+0x189/0x1f0 Fix by using goto to ensure locks acquired by trylock are always released, even when skipping VMAs without shareable locks. Link: https://lkml.kernel.org/r/20250926033255.10930-1-kartikey406@gmail.com Fixes: 40549ba ("hugetlb: use new vma_lock for pmd sharing synchronization") Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com> Reported-by: syzbot+f26d7c75c26ec19790e7@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=f26d7c75c26ec19790e7 Suggested-by: Andrew Morton <akpm@linux-foundation.org> Cc: David Hildenbrand <david@redhat.com> Cc: Muchun Song <muchun.song@linux.dev> Cc: Oscar Salvador <osalvador@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent fb552b2 commit dd83609

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

fs/hugetlbfs/inode.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,14 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end,
478478
if (!hugetlb_vma_trylock_write(vma))
479479
continue;
480480

481+
/*
482+
* Skip VMAs without shareable locks. Per the design in commit
483+
* 40549ba8f8e0, these will be handled by remove_inode_hugepages()
484+
* called after this function with proper locking.
485+
*/
486+
if (!__vma_shareable_lock(vma))
487+
goto skip;
488+
481489
v_start = vma_offset_start(vma, start);
482490
v_end = vma_offset_end(vma, end);
483491

@@ -488,6 +496,7 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end,
488496
* vmas. Therefore, lock is not held when calling
489497
* unmap_hugepage_range for private vmas.
490498
*/
499+
skip:
491500
hugetlb_vma_unlock_write(vma);
492501
}
493502
}

0 commit comments

Comments
 (0)