Re: [PATCH 2/3] mm/hugetlb: preserve CMA flag when returning folios to the pool

From: Muchun Song

Date: Wed Oct 28 2026 - 09:56:46 EST




> On Oct 28, 2026, at 19:33, Kaitao Cheng <kaitao.cheng@xxxxxxxxx> wrote:
>
> From: Kaitao Cheng <chengkaitao@xxxxxxxxxx>
>
> When vmemmap restoration fails, add_hugetlb_folio() returns the folio
> to the hugetlb pool. It clears folio->private and restores only
> HPG_vmemmap_optimized, losing HPG_cma on CMA-allocated folios.
>
> A later successful free then bypasses hugetlb_cma_free_frozen_folio()
> and returns the pages through free_frozen_pages(). The CMA allocation
> bitmap remains set, so the range is unavailable for future CMA
> allocations.
>
> Save the CMA flag before resetting folio->private and restore it along
> with the vmemmap optimization flag.

We already knew this issue. Cc Zi Yan. Seems he hasn't sent a fix.

But we want a different solution. See:

https://lore.kernel.org/linux-mm/A1A14368-7A43-40ED-B2AB-C2EC2C5FFB1D@xxxxxxxxx/

Thanks,
Muchun

>
> Fixes: d2d786714080 ("mm/hugetlb: enable bootmem allocation from CMA areas")
> Closes: https://sashiko.dev/#/bug/linux-5363eb09-9c3c-4f8b-9f3c-a998a8c4b258
> Signed-off-by: Kaitao Cheng <chengkaitao@xxxxxxxxxx>
> ---
> mm/hugetlb.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 4a008afaedf9..8da4bab676c9 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1437,6 +1437,7 @@ void remove_hugetlb_folio(struct hstate *h, struct folio *folio,
> void add_hugetlb_folio(struct hstate *h, struct folio *folio,
> bool adjust_surplus)
> {
> + bool cma = folio_test_hugetlb_cma(folio);
> int nid = folio_nid(folio);
>
> VM_BUG_ON_FOLIO(!folio_test_hugetlb_vmemmap_optimized(folio), folio);
> @@ -1453,9 +1454,11 @@ void add_hugetlb_folio(struct hstate *h, struct folio *folio,
> }
>
> __folio_set_hugetlb(folio);
> - /* Clear all folio->private flags except hugetlb_vmemmap_optimized. */
> + /* Preserve the vmemmap optimization state and CMA allocation origin. */
> folio->private = NULL;
> folio_set_hugetlb_vmemmap_optimized(folio);
> + if (cma)
> + folio_set_hugetlb_cma(folio);
>
> arch_clear_hugetlb_flags(folio);
> enqueue_hugetlb_folio(h, folio);
> --
> 2.53.0
>