Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hugetlbfs: move lock assertions after early returns in huge_pmd_unshare()

When hugetlb_vmdelete_list() processes VMAs during truncate operations, it
may encounter VMAs where huge_pmd_unshare() is called without the required
shareable lock. This triggers an assertion failure in
hugetlb_vma_assert_locked().

The previous fix in commit dd83609b8898 ("hugetlbfs: skip VMAs without
shareable locks in hugetlb_vmdelete_list") skipped entire VMAs without
shareable locks to avoid the assertion. However, this prevented pages
from being unmapped and freed, causing a regression in
fallocate(PUNCH_HOLE) operations where pages were not freed immediately,
as reported by Mark Brown.

Instead of checking locks in the caller or skipping VMAs, move the lock
assertions in huge_pmd_unshare() to after the early return checks. The
assertions are only needed when actual PMD unsharing work will be
performed. If the function returns early because sz != PMD_SIZE or the
PMD is not shared, no locks are required and assertions should not fire.

This approach reverts the VMA skipping logic from commit dd83609b8898
("hugetlbfs: skip VMAs without shareable locks in hugetlb_vmdelete_list")
while moving the assertions to avoid the assertion failure, keeping all
the logic within huge_pmd_unshare() itself and allowing page unmapping and
freeing to proceed for all VMAs.

Link: https://lkml.kernel.org/r/20251014113344.21194-1-kartikey406@gmail.com
Fixes: dd83609b8898 ("hugetlbfs: skip VMAs without shareable locks in hugetlb_vmdelete_list")
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
Reported-by: <syzbot+f26d7c75c26ec19790e7@syzkaller.appspotmail.com>
Reported-by: Mark Brown <broonie@kernel.org>
Closes: https://syzkaller.appspot.com/bug?extid=f26d7c75c26ec19790e7
Suggested-by: David Hildenbrand <david@redhat.com>
Suggested-by: Oscar Salvador <osalvador@suse.de>
Tested-by: <syzbot+f26d7c75c26ec19790e7@syzkaller.appspotmail.com>
Acked-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Deepanshu Kartikey and committed by
Andrew Morton
cec944dd 4ba5a8a7

+2 -12
-9
fs/hugetlbfs/inode.c
··· 478 478 if (!hugetlb_vma_trylock_write(vma)) 479 479 continue; 480 480 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 - 489 481 v_start = vma_offset_start(vma, start); 490 482 v_end = vma_offset_end(vma, end); 491 483 ··· 488 496 * vmas. Therefore, lock is not held when calling 489 497 * unmap_hugepage_range for private vmas. 490 498 */ 491 - skip: 492 499 hugetlb_vma_unlock_write(vma); 493 500 } 494 501 }
+2 -3
mm/hugetlb.c
··· 7614 7614 p4d_t *p4d = p4d_offset(pgd, addr); 7615 7615 pud_t *pud = pud_offset(p4d, addr); 7616 7616 7617 - i_mmap_assert_write_locked(vma->vm_file->f_mapping); 7618 - hugetlb_vma_assert_locked(vma); 7619 7617 if (sz != PMD_SIZE) 7620 7618 return 0; 7621 7619 if (!ptdesc_pmd_is_shared(virt_to_ptdesc(ptep))) 7622 7620 return 0; 7623 - 7621 + i_mmap_assert_write_locked(vma->vm_file->f_mapping); 7622 + hugetlb_vma_assert_locked(vma); 7624 7623 pud_clear(pud); 7625 7624 /* 7626 7625 * Once our caller drops the rmap lock, some other process might be