Skip to content

Commit b76b469

Browse files
xzpeterakpm00
authored andcommitted
mm/hugetlb: fix missing hugetlb_lock for resv uncharge
There is a recent report on UFFDIO_COPY over hugetlb: https://lore.kernel.org/all/[email protected]/ 350: lockdep_assert_held(&hugetlb_lock); Should be an issue in hugetlb but triggered in an userfault context, where it goes into the unlikely path where two threads modifying the resv map together. Mike has a fix in that path for resv uncharge but it looks like the locking criteria was overlooked: hugetlb_cgroup_uncharge_folio_rsvd() will update the cgroup pointer, so it requires to be called with the lock held. Link: https://lkml.kernel.org/r/[email protected] Fixes: 79aa925 ("hugetlb_cgroup: fix reservation accounting") Signed-off-by: Peter Xu <[email protected]> Reported-by: [email protected] Reviewed-by: Mina Almasry <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 6db7412 commit b76b469

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

mm/hugetlb.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3268,9 +3268,12 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
32683268

32693269
rsv_adjust = hugepage_subpool_put_pages(spool, 1);
32703270
hugetlb_acct_memory(h, -rsv_adjust);
3271-
if (deferred_reserve)
3271+
if (deferred_reserve) {
3272+
spin_lock_irq(&hugetlb_lock);
32723273
hugetlb_cgroup_uncharge_folio_rsvd(hstate_index(h),
32733274
pages_per_huge_page(h), folio);
3275+
spin_unlock_irq(&hugetlb_lock);
3276+
}
32743277
}
32753278

32763279
if (!memcg_charge_ret)

0 commit comments

Comments
 (0)