Merge branch 'akpm' (patches from Andrew)
[linux-2.6-microblaze.git] / mm / page_alloc.c
index 58f7a32..d6e94cc 100644 (file)
@@ -349,20 +349,7 @@ compound_page_dtor * const compound_page_dtors[NR_COMPOUND_DTORS] = {
 
 int min_free_kbytes = 1024;
 int user_min_free_kbytes = -1;
-#ifdef CONFIG_DISCONTIGMEM
-/*
- * DiscontigMem defines memory ranges as separate pg_data_t even if the ranges
- * are not on separate NUMA nodes. Functionally this works but with
- * watermark_boost_factor, it can reclaim prematurely as the ranges can be
- * quite small. By default, do not boost watermarks on discontigmem as in
- * many cases very high-order allocations like THP are likely to be
- * unsupported and the premature reclaim offsets the advantage of long-term
- * fragmentation avoidance.
- */
-int watermark_boost_factor __read_mostly;
-#else
 int watermark_boost_factor __read_mostly = 15000;
-#endif
 int watermark_scale_factor = 10;
 
 static unsigned long nr_kernel_pages __initdata;
@@ -400,7 +387,7 @@ int page_group_by_mobility_disabled __read_mostly;
 static DEFINE_STATIC_KEY_TRUE(deferred_pages);
 
 /*
- * Calling kasan_free_pages() only after deferred memory initialization
+ * Calling kasan_poison_pages() only after deferred memory initialization
  * has completed. Poisoning pages during deferred memory init will greatly
  * lengthen the process and cause problem in large memory systems as the
  * deferred pages initialization is done with interrupt disabled.
@@ -412,15 +399,12 @@ static DEFINE_STATIC_KEY_TRUE(deferred_pages);
  * on-demand allocation and then freed again before the deferred pages
  * initialization is done, but this is not likely to happen.
  */
-static inline void kasan_free_nondeferred_pages(struct page *page, int order,
-                                               bool init, fpi_t fpi_flags)
+static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags)
 {
-       if (static_branch_unlikely(&deferred_pages))
-               return;
-       if (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
-                       (fpi_flags & FPI_SKIP_KASAN_POISON))
-               return;
-       kasan_free_pages(page, order, init);
+       return static_branch_unlikely(&deferred_pages) ||
+              (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
+               (fpi_flags & FPI_SKIP_KASAN_POISON)) ||
+              PageSkipKASanPoison(page);
 }
 
 /* Returns true if the struct page for the pfn is uninitialised */
@@ -471,13 +455,11 @@ defer_init(int nid, unsigned long pfn, unsigned long end_pfn)
        return false;
 }
 #else
-static inline void kasan_free_nondeferred_pages(struct page *page, int order,
-                                               bool init, fpi_t fpi_flags)
+static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags)
 {
-       if (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
-                       (fpi_flags & FPI_SKIP_KASAN_POISON))
-               return;
-       kasan_free_pages(page, order, init);
+       return (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
+               (fpi_flags & FPI_SKIP_KASAN_POISON)) ||
+              PageSkipKASanPoison(page);
 }
 
 static inline bool early_page_uninitialised(unsigned long pfn)
@@ -687,10 +669,53 @@ out:
        add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
 }
 
+static inline unsigned int order_to_pindex(int migratetype, int order)
+{
+       int base = order;
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+       if (order > PAGE_ALLOC_COSTLY_ORDER) {
+               VM_BUG_ON(order != pageblock_order);
+               base = PAGE_ALLOC_COSTLY_ORDER + 1;
+       }
+#else
+       VM_BUG_ON(order > PAGE_ALLOC_COSTLY_ORDER);
+#endif
+
+       return (MIGRATE_PCPTYPES * base) + migratetype;
+}
+
+static inline int pindex_to_order(unsigned int pindex)
+{
+       int order = pindex / MIGRATE_PCPTYPES;
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+       if (order > PAGE_ALLOC_COSTLY_ORDER) {
+               order = pageblock_order;
+               VM_BUG_ON(order != pageblock_order);
+       }
+#else
+       VM_BUG_ON(order > PAGE_ALLOC_COSTLY_ORDER);
+#endif
+
+       return order;
+}
+
+static inline bool pcp_allowed_order(unsigned int order)
+{
+       if (order <= PAGE_ALLOC_COSTLY_ORDER)
+               return true;
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+       if (order == pageblock_order)
+               return true;
+#endif
+       return false;
+}
+
 static inline void free_the_page(struct page *page, unsigned int order)
 {
-       if (order == 0)         /* Via pcp? */
-               free_unref_page(page);
+       if (pcp_allowed_order(order))           /* Via pcp? */
+               free_unref_page(page, order);
        else
                __free_pages_ok(page, order, FPI_NONE);
 }
@@ -713,7 +738,7 @@ static inline void free_the_page(struct page *page, unsigned int order)
 void free_compound_page(struct page *page)
 {
        mem_cgroup_uncharge(page);
-       __free_pages_ok(page, compound_order(page), FPI_NONE);
+       free_the_page(page, compound_order(page));
 }
 
 void prep_compound_page(struct page *page, unsigned int order)
@@ -724,7 +749,6 @@ void prep_compound_page(struct page *page, unsigned int order)
        __SetPageHead(page);
        for (i = 1; i < nr_pages; i++) {
                struct page *p = page + i;
-               set_page_count(p, 0);
                p->mapping = TAIL_MAPPING;
                set_compound_head(p, page);
        }
@@ -1252,10 +1276,16 @@ out:
        return ret;
 }
 
-static void kernel_init_free_pages(struct page *page, int numpages)
+static void kernel_init_free_pages(struct page *page, int numpages, bool zero_tags)
 {
        int i;
 
+       if (zero_tags) {
+               for (i = 0; i < numpages; i++)
+                       tag_clear_highpage(page + i);
+               return;
+       }
+
        /* s390's use of memset() could override KASAN redzones. */
        kasan_disable_current();
        for (i = 0; i < numpages; i++) {
@@ -1271,7 +1301,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
                        unsigned int order, bool check_free, fpi_t fpi_flags)
 {
        int bad = 0;
-       bool init;
+       bool skip_kasan_poison = should_skip_kasan_poison(page, fpi_flags);
 
        VM_BUG_ON_PAGE(PageTail(page), page);
 
@@ -1340,10 +1370,17 @@ static __always_inline bool free_pages_prepare(struct page *page,
         * With hardware tag-based KASAN, memory tags must be set before the
         * page becomes unavailable via debug_pagealloc or arch_free_page.
         */
-       init = want_init_on_free();
-       if (init && !kasan_has_integrated_init())
-               kernel_init_free_pages(page, 1 << order);
-       kasan_free_nondeferred_pages(page, order, init, fpi_flags);
+       if (kasan_has_integrated_init()) {
+               if (!skip_kasan_poison)
+                       kasan_free_pages(page, order);
+       } else {
+               bool init = want_init_on_free();
+
+               if (init)
+                       kernel_init_free_pages(page, 1 << order, false);
+               if (!skip_kasan_poison)
+                       kasan_poison_pages(page, order, init);
+       }
 
        /*
         * arch_free_page() can make the page's contents inaccessible.  s390
@@ -1363,9 +1400,9 @@ static __always_inline bool free_pages_prepare(struct page *page,
  * to pcp lists. With debug_pagealloc also enabled, they are also rechecked when
  * moved from pcp lists to free lists.
  */
-static bool free_pcp_prepare(struct page *page)
+static bool free_pcp_prepare(struct page *page, unsigned int order)
 {
-       return free_pages_prepare(page, 0, true, FPI_NONE);
+       return free_pages_prepare(page, order, true, FPI_NONE);
 }
 
 static bool bulkfree_pcp_prepare(struct page *page)
@@ -1382,12 +1419,12 @@ static bool bulkfree_pcp_prepare(struct page *page)
  * debug_pagealloc enabled, they are checked also immediately when being freed
  * to the pcp lists.
  */
-static bool free_pcp_prepare(struct page *page)
+static bool free_pcp_prepare(struct page *page, unsigned int order)
 {
        if (debug_pagealloc_enabled_static())
-               return free_pages_prepare(page, 0, true, FPI_NONE);
+               return free_pages_prepare(page, order, true, FPI_NONE);
        else
-               return free_pages_prepare(page, 0, false, FPI_NONE);
+               return free_pages_prepare(page, order, false, FPI_NONE);
 }
 
 static bool bulkfree_pcp_prepare(struct page *page)
@@ -1419,8 +1456,10 @@ static inline void prefetch_buddy(struct page *page)
 static void free_pcppages_bulk(struct zone *zone, int count,
                                        struct per_cpu_pages *pcp)
 {
-       int migratetype = 0;
+       int pindex = 0;
        int batch_free = 0;
+       int nr_freed = 0;
+       unsigned int order;
        int prefetch_nr = READ_ONCE(pcp->batch);
        bool isolated_pageblocks;
        struct page *page, *tmp;
@@ -1431,7 +1470,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
         * below while (list_empty(list)) loop.
         */
        count = min(pcp->count, count);
-       while (count) {
+       while (count > 0) {
                struct list_head *list;
 
                /*
@@ -1443,24 +1482,31 @@ static void free_pcppages_bulk(struct zone *zone, int count,
                 */
                do {
                        batch_free++;
-                       if (++migratetype == MIGRATE_PCPTYPES)
-                               migratetype = 0;
-                       list = &pcp->lists[migratetype];
+                       if (++pindex == NR_PCP_LISTS)
+                               pindex = 0;
+                       list = &pcp->lists[pindex];
                } while (list_empty(list));
 
                /* This is the only non-empty list. Free them all. */
-               if (batch_free == MIGRATE_PCPTYPES)
+               if (batch_free == NR_PCP_LISTS)
                        batch_free = count;
 
+               order = pindex_to_order(pindex);
+               BUILD_BUG_ON(MAX_ORDER >= (1<<NR_PCP_ORDER_WIDTH));
                do {
                        page = list_last_entry(list, struct page, lru);
                        /* must delete to avoid corrupting pcp list */
                        list_del(&page->lru);
-                       pcp->count--;
+                       nr_freed += 1 << order;
+                       count -= 1 << order;
 
                        if (bulkfree_pcp_prepare(page))
                                continue;
 
+                       /* Encode order with the migratetype */
+                       page->index <<= NR_PCP_ORDER_WIDTH;
+                       page->index |= order;
+
                        list_add_tail(&page->lru, &head);
 
                        /*
@@ -1476,8 +1522,9 @@ static void free_pcppages_bulk(struct zone *zone, int count,
                                prefetch_buddy(page);
                                prefetch_nr--;
                        }
-               } while (--count && --batch_free && !list_empty(list));
+               } while (count > 0 && --batch_free && !list_empty(list));
        }
+       pcp->count -= nr_freed;
 
        /*
         * local_lock_irq held so equivalent to spin_lock_irqsave for
@@ -1492,14 +1539,19 @@ static void free_pcppages_bulk(struct zone *zone, int count,
         */
        list_for_each_entry_safe(page, tmp, &head, lru) {
                int mt = get_pcppage_migratetype(page);
+
+               /* mt has been encoded with the order (see above) */
+               order = mt & NR_PCP_ORDER_MASK;
+               mt >>= NR_PCP_ORDER_WIDTH;
+
                /* MIGRATE_ISOLATE page should not go to pcplists */
                VM_BUG_ON_PAGE(is_migrate_isolate(mt), page);
                /* Pageblock could have been isolated meanwhile */
                if (unlikely(isolated_pageblocks))
                        mt = get_pageblock_migratetype(page);
 
-               __free_one_page(page, page_to_pfn(page), zone, 0, mt, FPI_NONE);
-               trace_mm_page_pcpu_drain(page, 0, mt);
+               __free_one_page(page, page_to_pfn(page), zone, order, mt, FPI_NONE);
+               trace_mm_page_pcpu_drain(page, order, mt);
        }
        spin_unlock(&zone->lock);
 }
@@ -1647,7 +1699,7 @@ void __free_pages_core(struct page *page, unsigned int order)
        __free_pages_ok(page, order, FPI_TO_TAIL | FPI_SKIP_KASAN_POISON);
 }
 
-#ifdef CONFIG_NEED_MULTIPLE_NODES
+#ifdef CONFIG_NUMA
 
 /*
  * During memory init memblocks map pfns to nids. The search is expensive and
@@ -1697,7 +1749,7 @@ int __meminit early_pfn_to_nid(unsigned long pfn)
 
        return nid;
 }
-#endif /* CONFIG_NEED_MULTIPLE_NODES */
+#endif /* CONFIG_NUMA */
 
 void __init memblock_free_pages(struct page *page, unsigned long pfn,
                                                        unsigned int order)
@@ -2354,8 +2406,6 @@ static bool check_new_pages(struct page *page, unsigned int order)
 inline void post_alloc_hook(struct page *page, unsigned int order,
                                gfp_t gfp_flags)
 {
-       bool init;
-
        set_page_private(page, 0);
        set_page_refcounted(page);
 
@@ -2374,10 +2424,16 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
         * kasan_alloc_pages and kernel_init_free_pages must be
         * kept together to avoid discrepancies in behavior.
         */
-       init = !want_init_on_free() && want_init_on_alloc(gfp_flags);
-       kasan_alloc_pages(page, order, init);
-       if (init && !kasan_has_integrated_init())
-               kernel_init_free_pages(page, 1 << order);
+       if (kasan_has_integrated_init()) {
+               kasan_alloc_pages(page, order, gfp_flags);
+       } else {
+               bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags);
+
+               kasan_unpoison_pages(page, order, init);
+               if (init)
+                       kernel_init_free_pages(page, 1 << order,
+                                              gfp_flags & __GFP_ZEROTAGS);
+       }
 
        set_page_owner(page, order, gfp_flags);
 }
@@ -3136,7 +3192,7 @@ static void __drain_all_pages(struct zone *zone, bool force_all_cpus)
        int cpu;
 
        /*
-        * Allocate in the BSS so we wont require allocation in
+        * Allocate in the BSS so we won't require allocation in
         * direct reclaim path for CONFIG_CPUMASK_OFFSTACK=y
         */
        static cpumask_t cpus_with_pcps;
@@ -3276,11 +3332,12 @@ void mark_free_pages(struct zone *zone)
 }
 #endif /* CONFIG_PM */
 
-static bool free_unref_page_prepare(struct page *page, unsigned long pfn)
+static bool free_unref_page_prepare(struct page *page, unsigned long pfn,
+                                                       unsigned int order)
 {
        int migratetype;
 
-       if (!free_pcp_prepare(page))
+       if (!free_pcp_prepare(page, order))
                return false;
 
        migratetype = get_pfnblock_migratetype(page, pfn);
@@ -3330,16 +3387,18 @@ static int nr_pcp_high(struct per_cpu_pages *pcp, struct zone *zone)
 }
 
 static void free_unref_page_commit(struct page *page, unsigned long pfn,
-                                  int migratetype)
+                                  int migratetype, unsigned int order)
 {
        struct zone *zone = page_zone(page);
        struct per_cpu_pages *pcp;
        int high;
+       int pindex;
 
        __count_vm_event(PGFREE);
        pcp = this_cpu_ptr(zone->per_cpu_pageset);
-       list_add(&page->lru, &pcp->lists[migratetype]);
-       pcp->count++;
+       pindex = order_to_pindex(migratetype, order);
+       list_add(&page->lru, &pcp->lists[pindex]);
+       pcp->count += 1 << order;
        high = nr_pcp_high(pcp, zone);
        if (pcp->count >= high) {
                int batch = READ_ONCE(pcp->batch);
@@ -3349,15 +3408,15 @@ static void free_unref_page_commit(struct page *page, unsigned long pfn,
 }
 
 /*
- * Free a 0-order page
+ * Free a pcp page
  */
-void free_unref_page(struct page *page)
+void free_unref_page(struct page *page, unsigned int order)
 {
        unsigned long flags;
        unsigned long pfn = page_to_pfn(page);
        int migratetype;
 
-       if (!free_unref_page_prepare(page, pfn))
+       if (!free_unref_page_prepare(page, pfn, order))
                return;
 
        /*
@@ -3370,14 +3429,14 @@ void free_unref_page(struct page *page)
        migratetype = get_pcppage_migratetype(page);
        if (unlikely(migratetype >= MIGRATE_PCPTYPES)) {
                if (unlikely(is_migrate_isolate(migratetype))) {
-                       free_one_page(page_zone(page), page, pfn, 0, migratetype, FPI_NONE);
+                       free_one_page(page_zone(page), page, pfn, order, migratetype, FPI_NONE);
                        return;
                }
                migratetype = MIGRATE_MOVABLE;
        }
 
        local_lock_irqsave(&pagesets.lock, flags);
-       free_unref_page_commit(page, pfn, migratetype);
+       free_unref_page_commit(page, pfn, migratetype, order);
        local_unlock_irqrestore(&pagesets.lock, flags);
 }
 
@@ -3394,7 +3453,7 @@ void free_unref_page_list(struct list_head *list)
        /* Prepare pages for freeing */
        list_for_each_entry_safe(page, next, list, lru) {
                pfn = page_to_pfn(page);
-               if (!free_unref_page_prepare(page, pfn))
+               if (!free_unref_page_prepare(page, pfn, 0))
                        list_del(&page->lru);
 
                /*
@@ -3426,7 +3485,7 @@ void free_unref_page_list(struct list_head *list)
                set_page_private(page, 0);
                migratetype = get_pcppage_migratetype(page);
                trace_mm_page_free_batched(page);
-               free_unref_page_commit(page, pfn, migratetype);
+               free_unref_page_commit(page, pfn, migratetype, 0);
 
                /*
                 * Guard against excessive IRQ disabled times when we get
@@ -3562,7 +3621,8 @@ static inline void zone_statistics(struct zone *preferred_zone, struct zone *z,
 
 /* Remove page from the per-cpu list, caller must protect the list */
 static inline
-struct page *__rmqueue_pcplist(struct zone *zone, int migratetype,
+struct page *__rmqueue_pcplist(struct zone *zone, unsigned int order,
+                       int migratetype,
                        unsigned int alloc_flags,
                        struct per_cpu_pages *pcp,
                        struct list_head *list)
@@ -3571,16 +3631,30 @@ struct page *__rmqueue_pcplist(struct zone *zone, int migratetype,
 
        do {
                if (list_empty(list)) {
-                       pcp->count += rmqueue_bulk(zone, 0,
-                                       READ_ONCE(pcp->batch), list,
+                       int batch = READ_ONCE(pcp->batch);
+                       int alloced;
+
+                       /*
+                        * Scale batch relative to order if batch implies
+                        * free pages can be stored on the PCP. Batch can
+                        * be 1 for small zones or for boot pagesets which
+                        * should never store free pages as the pages may
+                        * belong to arbitrary zones.
+                        */
+                       if (batch > 1)
+                               batch = max(batch >> order, 2);
+                       alloced = rmqueue_bulk(zone, order,
+                                       batch, list,
                                        migratetype, alloc_flags);
+
+                       pcp->count += alloced << order;
                        if (unlikely(list_empty(list)))
                                return NULL;
                }
 
                page = list_first_entry(list, struct page, lru);
                list_del(&page->lru);
-               pcp->count--;
+               pcp->count -= 1 << order;
        } while (check_new_pcp(page));
 
        return page;
@@ -3588,8 +3662,9 @@ struct page *__rmqueue_pcplist(struct zone *zone, int migratetype,
 
 /* Lock and remove page from the per-cpu list */
 static struct page *rmqueue_pcplist(struct zone *preferred_zone,
-                       struct zone *zone, gfp_t gfp_flags,
-                       int migratetype, unsigned int alloc_flags)
+                       struct zone *zone, unsigned int order,
+                       gfp_t gfp_flags, int migratetype,
+                       unsigned int alloc_flags)
 {
        struct per_cpu_pages *pcp;
        struct list_head *list;
@@ -3605,8 +3680,8 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone,
         */
        pcp = this_cpu_ptr(zone->per_cpu_pageset);
        pcp->free_factor >>= 1;
-       list = &pcp->lists[migratetype];
-       page = __rmqueue_pcplist(zone,  migratetype, alloc_flags, pcp, list);
+       list = &pcp->lists[order_to_pindex(migratetype, order)];
+       page = __rmqueue_pcplist(zone, order, migratetype, alloc_flags, pcp, list);
        local_unlock_irqrestore(&pagesets.lock, flags);
        if (page) {
                __count_zid_vm_events(PGALLOC, page_zonenum(page), 1);
@@ -3627,15 +3702,15 @@ struct page *rmqueue(struct zone *preferred_zone,
        unsigned long flags;
        struct page *page;
 
-       if (likely(order == 0)) {
+       if (likely(pcp_allowed_order(order))) {
                /*
                 * MIGRATE_MOVABLE pcplist could have the pages on CMA area and
                 * we need to skip it when CMA area isn't allowed.
                 */
                if (!IS_ENABLED(CONFIG_CMA) || alloc_flags & ALLOC_CMA ||
                                migratetype != MIGRATE_MOVABLE) {
-                       page = rmqueue_pcplist(preferred_zone, zone, gfp_flags,
-                                       migratetype, alloc_flags);
+                       page = rmqueue_pcplist(preferred_zone, zone, order,
+                                       gfp_flags, migratetype, alloc_flags);
                        goto out;
                }
        }
@@ -3756,7 +3831,7 @@ static inline bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
 
 #endif /* CONFIG_FAIL_PAGE_ALLOC */
 
-noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
+static noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
 {
        return __should_fail_alloc_page(gfp_mask, order);
 }
@@ -5214,7 +5289,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
        /* Attempt the batch allocation */
        local_lock_irqsave(&pagesets.lock, flags);
        pcp = this_cpu_ptr(zone->per_cpu_pageset);
-       pcp_list = &pcp->lists[ac.migratetype];
+       pcp_list = &pcp->lists[order_to_pindex(ac.migratetype, 0)];
 
        while (nr_populated < nr_pages) {
 
@@ -5224,7 +5299,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
                        continue;
                }
 
-               page = __rmqueue_pcplist(zone, ac.migratetype, alloc_flags,
+               page = __rmqueue_pcplist(zone, 0, ac.migratetype, alloc_flags,
                                                                pcp, pcp_list);
                if (unlikely(!page)) {
                        /* Try and get at least one page */
@@ -6560,7 +6635,7 @@ static void __meminit zone_init_free_lists(struct zone *zone)
        }
 }
 
-#if !defined(CONFIG_FLAT_NODE_MEM_MAP)
+#if !defined(CONFIG_FLATMEM)
 /*
  * Only struct pages that correspond to ranges defined by memblock.memory
  * are zeroed and initialized by going through __init_single_page() during
@@ -6726,7 +6801,7 @@ static int zone_highsize(struct zone *zone, int batch, int cpu_online)
 {
 #ifdef CONFIG_MMU
        int high;
-       int nr_local_cpus;
+       int nr_split_cpus;
        unsigned long total_pages;
 
        if (!percpu_pagelist_high_fraction) {
@@ -6749,10 +6824,14 @@ static int zone_highsize(struct zone *zone, int batch, int cpu_online)
         * Split the high value across all online CPUs local to the zone. Note
         * that early in boot that CPUs may not be online yet and that during
         * CPU hotplug that the cpumask is not yet updated when a CPU is being
-        * onlined.
+        * onlined. For memory nodes that have no CPUs, split pcp->high across
+        * all online CPUs to mitigate the risk that reclaim is triggered
+        * prematurely due to pages stored on pcp lists.
         */
-       nr_local_cpus = max(1U, cpumask_weight(cpumask_of_node(zone_to_nid(zone)))) + cpu_online;
-       high = total_pages / nr_local_cpus;
+       nr_split_cpus = cpumask_weight(cpumask_of_node(zone_to_nid(zone))) + cpu_online;
+       if (!nr_split_cpus)
+               nr_split_cpus = num_online_cpus();
+       high = total_pages / nr_split_cpus;
 
        /*
         * Ensure high is at least batch*4. The multiple is based on the
@@ -6791,13 +6870,13 @@ static void pageset_update(struct per_cpu_pages *pcp, unsigned long high,
 
 static void per_cpu_pages_init(struct per_cpu_pages *pcp, struct per_cpu_zonestat *pzstats)
 {
-       int migratetype;
+       int pindex;
 
        memset(pcp, 0, sizeof(*pcp));
        memset(pzstats, 0, sizeof(*pzstats));
 
-       for (migratetype = 0; migratetype < MIGRATE_PCPTYPES; migratetype++)
-               INIT_LIST_HEAD(&pcp->lists[migratetype]);
+       for (pindex = 0; pindex < NR_PCP_LISTS; pindex++)
+               INIT_LIST_HEAD(&pcp->lists[pindex]);
 
        /*
         * Set batch and high values safe for a boot pageset. A true percpu
@@ -7416,7 +7495,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat)
        }
 }
 
-#ifdef CONFIG_FLAT_NODE_MEM_MAP
+#ifdef CONFIG_FLATMEM
 static void __ref alloc_node_mem_map(struct pglist_data *pgdat)
 {
        unsigned long __maybe_unused start = 0;
@@ -7451,7 +7530,7 @@ static void __ref alloc_node_mem_map(struct pglist_data *pgdat)
        pr_debug("%s: node %d, pgdat %08lx, node_mem_map %08lx\n",
                                __func__, pgdat->node_id, (unsigned long)pgdat,
                                (unsigned long)pgdat->node_mem_map);
-#ifndef CONFIG_NEED_MULTIPLE_NODES
+#ifndef CONFIG_NUMA
        /*
         * With no DISCONTIG, the global mem_map is just set as node 0's
         */
@@ -7464,7 +7543,7 @@ static void __ref alloc_node_mem_map(struct pglist_data *pgdat)
 }
 #else
 static void __ref alloc_node_mem_map(struct pglist_data *pgdat) { }
-#endif /* CONFIG_FLAT_NODE_MEM_MAP */
+#endif /* CONFIG_FLATMEM */
 
 #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
 static inline void pgdat_set_deferred_range(pg_data_t *pgdat)