Re: [PATCH 10/12] mm: hugetlb_vmemmap: make vmemmap restoration folio-oriented
From: Lance Yang
Date: Thu Oct 22 2026 - 23:47:13 EST
On Tue, Oct 20, 2026 at 07:58:22PM +0800, Muchun Song wrote:
>Like optimization, vmemmap restoration operates on one folio at a time,
>but the current interface exposes a raw address range and requires the
>HugeTLB caller to prepare part of the operation. This splits the common
>mechanism across layers and obscures its natural unit of work.
>
>Make the folio the unit of vmemmap restoration and move the common
>mechanics behind a folio-oriented interface. This keeps HugeTLB-specific
>eligibility and state in the caller and gives both directions of HVO
>consistent folio-level interfaces.
>
>No functional change intended.
>
>Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx>
>---
> mm/hugetlb_vmemmap.c | 37 +++++++++++++------------------------
> 1 file changed, 13 insertions(+), 24 deletions(-)
>
>diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
>index b76203e34881..97748a9cefe2 100644
>--- a/mm/hugetlb_vmemmap.c
>+++ b/mm/hugetlb_vmemmap.c
>@@ -360,28 +360,29 @@ static int vmemmap_optimize_folio(const struct folio *folio,
> }
>
> /**
>- * vmemmap_remap_alloc - remap the vmemmap virtual address range [@start, end)
>- * to the page which is from the @vmemmap_pages
>- * respectively.
>- * @start: start address of the vmemmap virtual address range that we want
>- * to remap.
>- * @end: end address of the vmemmap virtual address range that we want to
>- * remap.
>- * @flags: modifications to vmemmap_remap_walk flags
>+ * vmemmap_restore_folio - restore the vmemmap backing of a folio
>+ * @folio: folio whose vmemmap pages should be restored.
>+ * @flags: vmemmap remap control flags passed to vmemmap_remap_walk.
>+ *
>+ * Remap @folio's vmemmap so optimizable entries are restored from the shared
>+ * tail page back to distinct backing pages allocated for @folio, while
>+ * non-optimizable entries remain unchanged.
> *
> * Return: %0 on success, negative error code otherwise.
> */
>-static int vmemmap_remap_alloc(unsigned long start, unsigned long end,
>- unsigned long flags)
>+static int vmemmap_restore_folio(const struct folio *folio, unsigned long flags)
> {
> LIST_HEAD(vmemmap_pages);
>- int nid = page_to_nid((struct page *)start);
>+ int nid = folio_nid(folio);
>+ unsigned long start = (unsigned long)folio_page(folio, 0);
>+ unsigned long end = start + folio_vmemmap_size(folio);
> struct vmemmap_remap_walk walk = {
> .remap_pte = vmemmap_restore_pte,
> .vmemmap_pages = &vmemmap_pages,
> .flags = flags,
> };
>
>+ start += VMEMMAP_OPTIMIZATION_SIZE;
> if (alloc_vmemmap_page_list(&vmemmap_pages, (end - start) / PAGE_SIZE, nid))
> return -ENOMEM;
>
>@@ -399,7 +400,6 @@ static int __hugetlb_vmemmap_restore_folio(const struct hstate *h,
> struct folio *folio, unsigned long flags)
> {
> int ret;
>- unsigned long vmemmap_start, vmemmap_end;
>
> VM_WARN_ON_ONCE_FOLIO(!folio_test_hugetlb(folio), folio);
> VM_WARN_ON_ONCE_FOLIO(folio_ref_count(folio), folio);
>@@ -407,18 +407,7 @@ static int __hugetlb_vmemmap_restore_folio(const struct hstate *h,
> if (!folio_test_hugetlb_vmemmap_optimized(folio))
> return 0;
>
>- vmemmap_start = (unsigned long)&folio->page;
>- vmemmap_end = vmemmap_start + hugetlb_vmemmap_size(h);
>-
>- vmemmap_start += VMEMMAP_OPTIMIZATION_SIZE;
>-
>- /*
>- * The pages which the vmemmap virtual address range [@vmemmap_start,
>- * @vmemmap_end) are mapped to are freed to the buddy allocator.
>- * When a HugeTLB page is freed to the buddy allocator, previously
>- * discarded vmemmap pages must be allocated and remapping.
>- */
>- ret = vmemmap_remap_alloc(vmemmap_start, vmemmap_end, flags);
>+ ret = vmemmap_restore_folio(folio, flags);
Nit: we don't use h in __hugetlb_vmemmap_restore_folio() anymore. Could
we drop it from that helper while at it?
Otherwise, LGTM!
Reviewed-by: Lance Yang <lance.yang@xxxxxxxxx>