Skip to content

Commit fe3a40e

Browse files
xzpeterSasha Levin
authored andcommitted
mm/hugetlb: fix missing hugetlb_lock for resv uncharge
[ Upstream commit b76b469 ] 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]> Signed-off-by: Sasha Levin <[email protected]>
1 parent ed61406 commit fe3a40e

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
@@ -3190,9 +3190,12 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
31903190

31913191
rsv_adjust = hugepage_subpool_put_pages(spool, 1);
31923192
hugetlb_acct_memory(h, -rsv_adjust);
3193-
if (deferred_reserve)
3193+
if (deferred_reserve) {
3194+
spin_lock_irq(&hugetlb_lock);
31943195
hugetlb_cgroup_uncharge_folio_rsvd(hstate_index(h),
31953196
pages_per_huge_page(h), folio);
3197+
spin_unlock_irq(&hugetlb_lock);
3198+
}
31963199
}
31973200
return page;
31983201

0 commit comments

Comments
 (0)