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

From: Kaitao Cheng

Date: Wed Oct 28 2026 - 07:39:01 EST


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.

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