Skip to content

Commit cec944d

Browse files
deepanshu406akpm00
authored andcommitted
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 dd83609 ("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 dd83609 ("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: dd83609 ("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>
1 parent 4ba5a8a commit cec944d

2 files changed

Lines changed: 2 additions & 12 deletions

File tree

fs/hugetlbfs/inode.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -478,14 +478,6 @@ 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-
489481
v_start = vma_offset_start(vma, start);
490482
v_end = vma_offset_end(vma, end);
491483

@@ -496,7 +488,6 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end,
496488
* vmas. Therefore, lock is not held when calling
497489
* unmap_hugepage_range for private vmas.
498490
*/
499-
skip:
500491
hugetlb_vma_unlock_write(vma);
501492
}
502493
}

mm/hugetlb.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7614,13 +7614,12 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
76147614
p4d_t *p4d = p4d_offset(pgd, addr);
76157615
pud_t *pud = pud_offset(p4d, addr);
76167616

7617-
i_mmap_assert_write_locked(vma->vm_file->f_mapping);
7618-
hugetlb_vma_assert_locked(vma);
76197617
if (sz != PMD_SIZE)
76207618
return 0;
76217619
if (!ptdesc_pmd_is_shared(virt_to_ptdesc(ptep)))
76227620
return 0;
7623-
7621+
i_mmap_assert_write_locked(vma->vm_file->f_mapping);
7622+
hugetlb_vma_assert_locked(vma);
76247623
pud_clear(pud);
76257624
/*
76267625
* Once our caller drops the rmap lock, some other process might be

0 commit comments

Comments
 (0)