alloc_hugetlb_folio() calls hugepage_subpool_get_pages() when map_chg is set. For subpools with max_hpages, that increments used_hpages even when the returned gbl_chg is positive. If a later hugetlb cgroup charge fails, the cleanup currently calls hugepage_subpool_put_pages() only for !gbl_chg. The gbl_chg > 0 path therefore leaks one used_hpages charge per failure. Always undo the subpool charge after a successful subpool get. Keep the global reservation accounting under !gbl_chg, because only that path consumed a reservation from the subpool. Signed-off-by: Catherine --- mm/hugetlb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index f24bf49be..b3ad024a0 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3026,12 +3026,14 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, h_cg); out_subpool_put: /* - * put page to subpool iff the quota of subpool's rsv_hpages is used - * during hugepage_subpool_get_pages. + * map_chg means hugepage_subpool_get_pages() succeeded above. + * Always undo the subpool quota charge; only drop global reservation + * accounting if the subpool consumed a reservation. */ - if (map_chg && !gbl_chg) { + if (map_chg) { gbl_reserve = hugepage_subpool_put_pages(spool, 1); - hugetlb_acct_memory(h, -gbl_reserve); + if (!gbl_chg) + hugetlb_acct_memory(h, -gbl_reserve); } -- 2.50.1 (Apple Git-155)