vmemmap_can_optimize() no longer needs to gate section activation. section_activate() can use pgmap->vmemmap_shift directly to record the requested section order and leave support checks to the vmemmap population path. That keeps the policy local to the code that actually instantiates the mapping, instead of requiring callers to pre-filter unsupported cases.
In particular, altmap-backed memmap allocation cannot support HVO, so __populate_section_memmap() clears any inherited optimized section order for full-section adds and rejects subsection re-adds. Unsupported optimized mappings are therefore rejected where the vmemmap backing is set up, and callers no longer have to care about that restriction. With that handling in place, vmemmap_can_optimize() becomes redundant and can be removed. Signed-off-by: Muchun Song <[email protected]> --- include/linux/mm.h | 34 ---------------------------------- mm/sparse-vmemmap.c | 14 +++++++++++++- 2 files changed, 13 insertions(+), 35 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 5e38c9a16a0a..5f45de90972d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -4896,40 +4896,6 @@ static inline void vmem_altmap_free(struct vmem_altmap *altmap, } #endif -#define VMEMMAP_RESERVE_NR OPTIMIZED_FOLIO_VMEMMAP_PAGES -#ifdef CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP -static inline bool __vmemmap_can_optimize(struct vmem_altmap *altmap, - struct dev_pagemap *pgmap) -{ - unsigned long nr_pages; - unsigned long nr_vmemmap_pages; - - if (!pgmap || !is_power_of_2(sizeof(struct page))) - return false; - - nr_pages = pgmap_vmemmap_nr(pgmap); - nr_vmemmap_pages = ((nr_pages * sizeof(struct page)) >> PAGE_SHIFT); - /* - * For vmemmap optimization with DAX we need minimum 2 vmemmap - * pages. See layout diagram in Documentation/mm/vmemmap_dedup.rst - */ - return !altmap && (nr_vmemmap_pages > VMEMMAP_RESERVE_NR); -} -/* - * If we don't have an architecture override, use the generic rule - */ -#ifndef vmemmap_can_optimize -#define vmemmap_can_optimize __vmemmap_can_optimize -#endif - -#else -static inline bool vmemmap_can_optimize(struct vmem_altmap *altmap, - struct dev_pagemap *pgmap) -{ - return false; -} -#endif - enum mf_flags { MF_COUNT_INCREASED = 1 << 0, MF_ACTION_REQUIRED = 1 << 1, diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 793fd4ce1393..549be01d90f8 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -384,11 +384,23 @@ struct page * __meminit __populate_section_memmap(unsigned long pfn, { unsigned long start = (unsigned long) pfn_to_page(pfn); unsigned long end = start + nr_pages * sizeof(struct page); + struct mem_section *ms = __pfn_to_section(pfn); if (WARN_ON_ONCE(!IS_ALIGNED(pfn, PAGES_PER_SUBSECTION) || !IS_ALIGNED(nr_pages, PAGES_PER_SUBSECTION))) return NULL; + /* HVO is not supported now when memmap pages are backed by an altmap. */ + if (altmap && section_vmemmap_optimizable(ms)) { + /* + * A subsection re-add can inherit order left by a partial + * remove after full add. + */ + if (nr_pages < PAGES_PER_SECTION) + return NULL; + section_set_order(ms, 0); + } + return vmemmap_populate(start, end, nid, altmap) ? NULL : (void *)start; } @@ -613,7 +625,7 @@ static struct page * __meminit section_activate(int nid, unsigned long pfn, unsigned int order; int rc; - order = vmemmap_can_optimize(altmap, pgmap) ? pgmap->vmemmap_shift : 0; + order = pgmap ? pgmap->vmemmap_shift : 0; /* All sub-sections within a section must share the same order. */ if (nr_pages < PAGES_PER_SECTION && section_order(ms) && section_order(ms) != order) return ERR_PTR(-ENOTSUPP); -- 2.54.0
