Make pfn_valid() return 0 for PFNs that fall into invalid subsections in early sections. Make for_each_valid_pfn() skip PFNs that fall into invalid subsections in early sections. This change is in preparation for optimizing zone contiguity checks based on pages_with_online_memmap. Reviewed-by: Wei Yang Reviewed-by: Jason Zeng Signed-off-by: Yuan Liu --- include/linux/mmzone.h | 13 ++++++------- mm/sparse-vmemmap.c | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9adb2ad21da5..783084f8bbfe 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -2259,6 +2259,10 @@ void sparse_init_early_section(int nid, struct page *map, unsigned long pnum, * there is actual usable memory at that @pfn. The struct page may * represent a hole or an unusable page frame. * + * Note that this function returns 0 for PFNs that fall into + * invalid subsections as part of early sections, even though there would + * currently be a memmap allocated (that should not be touched). + * * Return: 1 for PFNs that have memory map entries and 0 otherwise */ static inline int pfn_valid(unsigned long pfn) @@ -2283,11 +2287,7 @@ static inline int pfn_valid(unsigned long pfn) rcu_read_unlock_sched(); return 0; } - /* - * Traditionally early sections always returned pfn_valid() for - * the entire section-sized span. - */ - ret = early_section(ms) || pfn_section_valid(ms, pfn); + ret = pfn_section_valid(ms, pfn); rcu_read_unlock_sched(); return ret; @@ -2303,8 +2303,7 @@ static inline unsigned long first_valid_pfn(unsigned long pfn, unsigned long end while (nr <= __highest_present_section_nr && pfn < end_pfn) { struct mem_section *ms = __pfn_to_section(pfn); - if (valid_section(ms) && - (early_section(ms) || pfn_section_first_valid(ms, &pfn))) { + if (valid_section(ms) && pfn_section_first_valid(ms, &pfn)) { rcu_read_unlock_sched(); return pfn; } diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 6eadb9d116e4..c6eefbb6013f 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -771,8 +771,8 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, } /* - * The memmap of early sections is always fully populated. See - * section_activate() and pfn_valid() . + * The memmap of early sections is currently always fully populated. See + * section_activate(). */ if (!section_is_early) { memmap_pages_add(-1L * (DIV_ROUND_UP(nr_pages * sizeof(struct page), PAGE_SIZE))); -- 2.47.3