Restoring an optimized folio and rolling back a partial optimization both restore a vmemmap range, but the operation is currently implemented separately in each path. Use a single range-restoration path for both cases, making rollback an explicit bounded form of normal restoration. No functional change intended. Signed-off-by: Muchun Song Reviewed-by: Lance Yang Reviewed-by: Qi Zheng Reviewed-by: Mike Rapoport (Microsoft) Reviewed-by: Oscar Salvador Tested-by: Andrew Morton --- v4: - Collect Reviewed-by from Oscar Salvador - Collect Tested-by from Andrew Morton v3: - Collect Reviewed-by from Mike Rapoport v2: - Collect Reviewed-by from Lance Yang and Qi Zheng --- mm/hugetlb_vmemmap.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c index 359e53302a67..b8c10671d53b 100644 --- a/mm/hugetlb_vmemmap.c +++ b/mm/hugetlb_vmemmap.c @@ -287,6 +287,18 @@ static int vmemmap_restore_pte(pte_t *pte, unsigned long addr, return 0; } +static inline int vmemmap_restore_range(unsigned long start, unsigned long end, + struct list_head *vmemmap_pages, unsigned long flags) +{ + struct vmemmap_remap_walk walk = { + .remap_pte = vmemmap_restore_pte, + .vmemmap_pages = vmemmap_pages, + .flags = flags, + }; + + return vmemmap_remap_range(start, end, &walk); +} + /** * vmemmap_remap_split - split the vmemmap virtual address range [@start, @end) * backing PMDs of the directmap into PTEs @@ -348,19 +360,7 @@ static int vmemmap_optimize_folio(const struct folio *folio, return ret; end = start + walk.nr_walked * PAGE_SIZE; - - /* - * vmemmap_pages contains pages from the previous vmemmap_remap_range() - * call which failed. These are pages which were removed from - * the vmemmap. They will be restored in the following call. - */ - walk = (struct vmemmap_remap_walk) { - .remap_pte = vmemmap_restore_pte, - .vmemmap_pages = vmemmap_pages, - .flags = 0, - }; - - vmemmap_remap_range(start, end, &walk); + vmemmap_restore_range(start, end, vmemmap_pages, 0); return ret; } @@ -382,11 +382,6 @@ static int vmemmap_restore_folio(const struct folio *folio, unsigned long flags) unsigned long end = start + folio_vmemmap_size(folio); int ret, nid = folio_nid(folio); LIST_HEAD(vmemmap_pages); - struct vmemmap_remap_walk walk = { - .remap_pte = vmemmap_restore_pte, - .vmemmap_pages = &vmemmap_pages, - .flags = flags, - }; start += VMEMMAP_OPTIMIZATION_SIZE; ret = alloc_vmemmap_page_list(&vmemmap_pages, (end - start) / PAGE_SIZE, @@ -394,7 +389,7 @@ static int vmemmap_restore_folio(const struct folio *folio, unsigned long flags) if (ret) return ret; - return vmemmap_remap_range(start, end, &walk); + return vmemmap_restore_range(start, end, &vmemmap_pages, flags); } static bool vmemmap_optimize_enabled = IS_ENABLED(CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON); -- 2.54.0