From: Ackerley Tng When alloc_hugetlb_folio() fails early (e.g. buddy allocation failure or hugetlb cgroup charging failure) and gbl_chg == 1 (meaning a reservation was not used, but a global page was allocated instead), the subpool page acquired via hugepage_subpool_get_pages() must still be returned. Currently, the error path out_subpool_put: only calls hugepage_subpool_put_pages() if !gbl_chg is true. If gbl_chg is 1, it skips it, permanently leaking the subpool's used_hpages counter. With the earlier patch to always track used_hpages in the subpool, always call hugepage_subpool_put_pages() if map_chg is true to consistently restore the page to the subpool. Only call hugetlb_acct_memory() to adjust global reservations if gbl_chg == 0 since gbl_chg == 0 indicates a subpool (and global) reservation was used. Fixes: a833a693a490e ("mm: hugetlb: fix incorrect fallback for subpool") Cc: stable@vger.kernel.org Signed-off-by: Ackerley Tng --- mm/hugetlb.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 061d7250c202d..3f6189d2d0188 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2859,7 +2859,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, struct hugepage_subpool *spool = subpool_vma(vma); struct hstate *h = hstate_vma(vma); struct folio *folio; - long retval, gbl_chg, gbl_reserve; + long retval, gbl_chg; map_chg_state map_chg; int ret, idx; struct hugetlb_cgroup *h_cg = NULL; @@ -3009,13 +3009,11 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, hugetlb_cgroup_uncharge_cgroup_rsvd(idx, pages_per_huge_page(h), h_cg_rsvd); out_subpool_put: - /* - * put page to subpool iff the quota of subpool's rsv_hpages is used - * during hugepage_subpool_get_pages. - */ - if (map_chg && !gbl_chg) { - gbl_reserve = hugepage_subpool_put_pages(spool, 1); - hugetlb_acct_memory(h, -gbl_reserve); + if (map_chg) { + long gbl_reserve = hugepage_subpool_put_pages(spool, 1); + + if (!gbl_chg) + hugetlb_acct_memory(h, -gbl_reserve); } -- 2.55.0.229.g6434b31f56-goog