[PATCH v6 14/17] mm/hugetlb: remove HUGE_BOOTMEM_HVO

From: Muchun Song

Date: Thu Sep 10 2026 - 02:37:17 EST


The HUGE_BOOTMEM_HVO flag tracked whether a bootmem huge page had
already gone through the old early vmemmap optimization path.

Now that HugeTLB uses section-based vmemmap optimization, that state is
already reflected in the compound page order stored in section metadata.

Remove HUGE_BOOTMEM_HVO and its helper, and use the section state
directly when deciding whether to mark a folio as vmemmap-optimized.

Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx>
Acked-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx>
Acked-by: Qi Zheng <qi.zheng@xxxxxxxxx>
---
v6:
- Use the compound page order helper names
(suggested by David Hildenbrand)
- Collect Acked-by from Qi Zheng

v3:
- Use the order-based helper for the bootmem vmemmap-optimized check

v2:
- Collect Acked-by from Mike Rapoport
---
include/linux/hugetlb.h | 5 ++---
mm/hugetlb.c | 16 +++-------------
mm/hugetlb_vmemmap.c | 2 --
3 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index fe28f98e1b22..3559041a5a57 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -675,9 +675,8 @@ struct hstate {
char name[HSTATE_NAME_LEN];
};

-#define HUGE_BOOTMEM_HVO 0x0001
-#define HUGE_BOOTMEM_ZONES_VALID 0x0002
-#define HUGE_BOOTMEM_CMA 0x0004
+#define HUGE_BOOTMEM_ZONES_VALID BIT(0)
+#define HUGE_BOOTMEM_CMA BIT(1)

int isolate_or_dissolve_huge_folio(struct folio *folio, struct list_head *list);
int replace_free_hugepage_folios(unsigned long start_pfn, unsigned long end_pfn);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ee5567fcdbe9..fbc2ecafef9e 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3220,11 +3220,6 @@ static void __init hugetlb_folio_init_vmemmap(struct folio *folio,
prep_compound_head(&folio->page, huge_page_order(h));
}

-static bool __init hugetlb_bootmem_page_prehvo(struct huge_bootmem_page *m)
-{
- return m->flags & HUGE_BOOTMEM_HVO;
-}
-
static bool __init hugetlb_bootmem_page_earlycma(struct huge_bootmem_page *m)
{
return m->flags & HUGE_BOOTMEM_CMA;
@@ -3299,6 +3294,7 @@ static void __init gather_bootmem_prealloc_node(unsigned long nid)
list_for_each_entry_safe(m, tm, &huge_boot_pages[nid], list) {
struct page *page = virt_to_page(m);
struct folio *folio = (void *)page;
+ const unsigned long pfn = folio_pfn(folio);

h = m->hstate;
/*
@@ -3316,15 +3312,9 @@ static void __init gather_bootmem_prealloc_node(unsigned long nid)
HUGETLB_VMEMMAP_RESERVE_PAGES);
init_new_hugetlb_folio(folio);

- if (hugetlb_bootmem_page_prehvo(m))
- /*
- * If pre-HVO was done, just set the
- * flag, the HVO code will then skip
- * this folio.
- */
+ if (vmemmap_optimizable_order(pfn_to_section_compound_order(pfn)))
folio_set_hugetlb_vmemmap_optimized(folio);
- section_set_compound_order_range(folio_pfn(folio),
- folio_nr_pages(folio), 0);
+ section_set_compound_order_range(pfn, folio_nr_pages(folio), 0);

if (hugetlb_bootmem_page_earlycma(m))
folio_set_hugetlb_cma(folio);
diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index d1b031dcd177..fba0c5a7d46f 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -715,8 +715,6 @@ void __init hugetlb_vmemmap_optimize_bootmem_page(struct huge_bootmem_page *m)

section_set_compound_order_range(pfn, pages_per_huge_page(h),
huge_page_order(h));
- if (vmemmap_optimizable_order(pfn_to_section_compound_order(pfn)))
- m->flags |= HUGE_BOOTMEM_HVO;
}

static const struct ctl_table hugetlb_vmemmap_sysctls[] = {
--
2.54.0