From: Zi Yan <ziy@xxxxxxxxxx> MAX_ORDER is limited at a memory section size, thus widely used as a variable to indicate maximum physically contiguous page size. But this limitation is no longer necessary as kernel only supports sparse memory model. Add a new variable MAX_PHYS_CONTIG_ORDER to replace such uses of MAX_ORDER. Signed-off-by: Zi Yan <ziy@xxxxxxxxxx> --- Documentation/admin-guide/kernel-parameters.txt | 2 +- arch/sparc/mm/tsb.c | 4 ++-- arch/um/kernel/um_arch.c | 4 ++-- include/linux/pageblock-flags.h | 12 ++++++++++++ kernel/dma/pool.c | 8 ++++---- mm/hugetlb.c | 2 +- mm/internal.h | 8 ++++---- mm/memory.c | 4 ++-- mm/memory_hotplug.c | 6 +++--- mm/page_isolation.c | 2 +- mm/page_reporting.c | 4 ++-- 11 files changed, 34 insertions(+), 22 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index ff33971e1630..ec519225b671 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3899,7 +3899,7 @@ [KNL] Minimal page reporting order Format: <integer> Adjust the minimal page reporting order. The page - reporting is disabled when it exceeds MAX_ORDER. + reporting is disabled when it exceeds MAX_PHYS_CONTIG_ORDER. panic= [KNL] Kernel behaviour on panic: delay <timeout> timeout > 0: seconds before rebooting diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 912205787161..15c31d050dab 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c @@ -402,8 +402,8 @@ void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long rss) unsigned long new_rss_limit; gfp_t gfp_flags; - if (max_tsb_size > (PAGE_SIZE << MAX_ORDER)) - max_tsb_size = (PAGE_SIZE << MAX_ORDER); + if (max_tsb_size > (PAGE_SIZE << MAX_PHYS_CONTIG_ORDER)) + max_tsb_size = (PAGE_SIZE << MAX_PHYS_CONTIG_ORDER); new_cache_index = 0; for (new_size = 8192; new_size < max_tsb_size; new_size <<= 1UL) { diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index e0de60e503b9..52a474f4f1c7 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -368,10 +368,10 @@ int __init linux_main(int argc, char **argv) max_physmem = TASK_SIZE - uml_physmem - iomem_size - MIN_VMALLOC; /* - * Zones have to begin on a 1 << MAX_ORDER page boundary, + * Zones have to begin on a 1 << MAX_PHYS_CONTIG_ORDER page boundary, * so this makes sure that's true for highmem */ - max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); + max_physmem &= ~((1 << (PAGE_SHIFT + MAX_PHYS_CONTIG_ORDER)) - 1); if (physmem_size + iomem_size > max_physmem) { highmem = physmem_size + iomem_size - max_physmem; physmem_size -= highmem; diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h index 940efcffd374..358b871b07ca 100644 --- a/include/linux/pageblock-flags.h +++ b/include/linux/pageblock-flags.h @@ -54,6 +54,18 @@ extern unsigned int pageblock_order; #define pageblock_nr_pages (1UL << pageblock_order) +/* + * memory section is only defined in sparsemem and in flatmem, pages are always + * physically contiguous, but we use MAX_ORDER since all users assume so. + */ +#ifdef CONFIG_FLATMEM +#define MAX_PHYS_CONTIG_ORDER MAX_ORDER +#else /* SPARSEMEM */ +#define MAX_PHYS_CONTIG_ORDER (min(PFN_SECTION_SHIFT, MAX_ORDER)) +#endif /* CONFIG_FLATMEM */ + +#define MAX_PHYS_CONTIG_NR_PAGES (1UL << MAX_PHYS_CONTIG_ORDER) + /* Forward declaration */ struct page; diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c index e20f168a34c7..b10f1dd52871 100644 --- a/kernel/dma/pool.c +++ b/kernel/dma/pool.c @@ -84,8 +84,8 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size, void *addr; int ret = -ENOMEM; - /* Cannot allocate larger than MAX_ORDER */ - order = min(get_order(pool_size), MAX_ORDER); + /* Cannot allocate larger than MAX_PHYS_CONTIG_ORDER */ + order = min(get_order(pool_size), MAX_PHYS_CONTIG_ORDER); do { pool_size = 1 << (PAGE_SHIFT + order); @@ -190,11 +190,11 @@ static int __init dma_atomic_pool_init(void) /* * If coherent_pool was not used on the command line, default the pool - * sizes to 128KB per 1GB of memory, min 128KB, max MAX_ORDER. + * sizes to 128KB per 1GB of memory, min 128KB, max MAX_PHYS_CONTIG_ORDER. */ if (!atomic_pool_size) { unsigned long pages = totalram_pages() / (SZ_1G / SZ_128K); - pages = min_t(unsigned long, pages, MAX_ORDER_NR_PAGES); + pages = min_t(unsigned long, pages, MAX_PHYS_CONTIG_NR_PAGES); atomic_pool_size = max_t(size_t, pages << PAGE_SHIFT, SZ_128K); } INIT_WORK(&atomic_pool_work, atomic_pool_work_fn); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 15ff582687a3..36eedeed1b22 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1903,7 +1903,7 @@ pgoff_t hugetlb_basepage_index(struct page *page) pgoff_t index = page_index(page_head); unsigned long compound_idx; - if (compound_order(page_head) > MAX_ORDER) + if (compound_order(page_head) > MAX_PHYS_CONTIG_ORDER) compound_idx = page_to_pfn(page) - page_to_pfn(page_head); else compound_idx = page - page_head; diff --git a/mm/internal.h b/mm/internal.h index 4df67b6b8cce..1433e3a6fdd0 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -302,7 +302,7 @@ static inline bool page_is_buddy(struct page *page, struct page *buddy, * satisfies the following equation: * P = B & ~(1 << O) * - * Assumption: *_mem_map is contiguous at least up to MAX_ORDER + * Assumption: *_mem_map is contiguous at least up to MAX_PHYS_CONTIG_ORDER */ static inline unsigned long __find_buddy_pfn(unsigned long page_pfn, unsigned int order) @@ -642,11 +642,11 @@ static inline void vunmap_range_noflush(unsigned long start, unsigned long end) /* * Return the mem_map entry representing the 'offset' subpage within * the maximally aligned gigantic page 'base'. Handle any discontiguity - * in the mem_map at MAX_ORDER_NR_PAGES boundaries. + * in the mem_map at MAX_PHYS_CONTIG_NR_PAGES boundaries. */ static inline struct page *mem_map_offset(struct page *base, int offset) { - if (unlikely(offset >= MAX_ORDER_NR_PAGES)) + if (unlikely(offset >= MAX_PHYS_CONTIG_NR_PAGES)) return nth_page(base, offset); return base + offset; } @@ -658,7 +658,7 @@ static inline struct page *mem_map_offset(struct page *base, int offset) static inline struct page *mem_map_next(struct page *iter, struct page *base, int offset) { - if (unlikely((offset & (MAX_ORDER_NR_PAGES - 1)) == 0)) { + if (unlikely((offset & (MAX_PHYS_CONTIG_NR_PAGES - 1)) == 0)) { unsigned long pfn = page_to_pfn(base) + offset; if (!pfn_valid(pfn)) return NULL; diff --git a/mm/memory.c b/mm/memory.c index bd8e7e79be99..3b82945aaa3d 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -5660,7 +5660,7 @@ void clear_huge_page(struct page *page, unsigned long addr = addr_hint & ~(((unsigned long)pages_per_huge_page << PAGE_SHIFT) - 1); - if (unlikely(pages_per_huge_page > MAX_ORDER_NR_PAGES)) { + if (unlikely(pages_per_huge_page > MAX_PHYS_CONTIG_NR_PAGES)) { clear_gigantic_page(page, addr, pages_per_huge_page); return; } @@ -5713,7 +5713,7 @@ void copy_user_huge_page(struct page *dst, struct page *src, .vma = vma, }; - if (unlikely(pages_per_huge_page > MAX_ORDER_NR_PAGES)) { + if (unlikely(pages_per_huge_page > MAX_PHYS_CONTIG_NR_PAGES)) { copy_user_gigantic_page(dst, src, addr, vma, pages_per_huge_page); return; diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 5540499007ae..8930823e5067 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -596,16 +596,16 @@ static void online_pages_range(unsigned long start_pfn, unsigned long nr_pages) unsigned long pfn; /* - * Online the pages in MAX_ORDER aligned chunks. The callback might + * Online the pages in MAX_PHYS_CONTIG_ORDER aligned chunks. The callback might * decide to not expose all pages to the buddy (e.g., expose them * later). We account all pages as being online and belonging to this * zone ("present"). * When using memmap_on_memory, the range might not be aligned to - * MAX_ORDER_NR_PAGES - 1, but pageblock aligned. __ffs() will detect + * MAX_PHYS_CONTIG_NR_PAGES - 1, but pageblock aligned. __ffs() will detect * this and the first chunk to online will be pageblock_nr_pages. */ for (pfn = start_pfn; pfn < end_pfn;) { - int order = min_t(unsigned long, MAX_ORDER, __ffs(pfn)); + int order = min_t(unsigned long, MAX_PHYS_CONTIG_ORDER, __ffs(pfn)); (*online_page_callback)(pfn_to_page(pfn), order); pfn += (1UL << order); diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 8d33120a81b2..801835f91c44 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -226,7 +226,7 @@ static void unset_migratetype_isolate(struct page *page, int migratetype) */ if (PageBuddy(page)) { order = buddy_order(page); - if (order >= pageblock_order && order <= MAX_ORDER) { + if (order >= pageblock_order && order <= MAX_PHYS_CONTIG_ORDER) { buddy = find_buddy_page_pfn(page, page_to_pfn(page), order, NULL); if (buddy && !is_migrate_isolate_page(buddy)) { diff --git a/mm/page_reporting.c b/mm/page_reporting.c index d52a55bca6d5..b48d6ad82998 100644 --- a/mm/page_reporting.c +++ b/mm/page_reporting.c @@ -11,7 +11,7 @@ #include "page_reporting.h" #include "internal.h" -unsigned int page_reporting_order = MAX_ORDER + 1; +unsigned int page_reporting_order = MAX_PHYS_CONTIG_ORDER + 1; module_param(page_reporting_order, uint, 0644); MODULE_PARM_DESC(page_reporting_order, "Set page reporting order"); @@ -244,7 +244,7 @@ page_reporting_process_zone(struct page_reporting_dev_info *prdev, return err; /* Process each free list starting from lowest order/mt */ - for (order = page_reporting_order; order <= MAX_ORDER; order++) { + for (order = page_reporting_order; order <= MAX_PHYS_CONTIG_ORDER; order++) { for (mt = 0; mt < MIGRATE_TYPES; mt++) { /* We do not pull pages from the isolate free list */ if (is_migrate_isolate(mt)) -- 2.35.1