mm/sparsemem: Allocate mem_section at runtime for CONFIG_SPARSEMEM_EXTREME=y
[sfrench/cifs-2.6.git] / mm / page_alloc.c
index c841af88836ad63d548a2f007220203e4a8ddf9a..8dfd13f724d9666e713441680262032921e04249 100644 (file)
@@ -1190,7 +1190,7 @@ static void __meminit __init_single_pfn(unsigned long pfn, unsigned long zone,
 }
 
 #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
-static void init_reserved_page(unsigned long pfn)
+static void __meminit init_reserved_page(unsigned long pfn)
 {
        pg_data_t *pgdat;
        int nid, zid;
@@ -5367,6 +5367,7 @@ not_early:
 
                        __init_single_page(page, pfn, zone, nid);
                        set_pageblock_migratetype(page, MIGRATE_MOVABLE);
+                       cond_resched();
                } else {
                        __init_single_pfn(pfn, zone, nid);
                }
@@ -5645,6 +5646,16 @@ void __init sparse_memory_present_with_active_regions(int nid)
        unsigned long start_pfn, end_pfn;
        int i, this_nid;
 
+#ifdef CONFIG_SPARSEMEM_EXTREME
+       if (!mem_section) {
+               unsigned long size, align;
+
+               size = sizeof(struct mem_section) * NR_SECTION_ROOTS;
+               align = 1 << (INTERNODE_CACHE_SHIFT);
+               mem_section = memblock_virt_alloc(size, align);
+       }
+#endif
+
        for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, &this_nid)
                memory_present(this_nid, start_pfn, end_pfn);
 }