mm: stop zeroing memory during allocation in vmemmap
[sfrench/cifs-2.6.git] / mm / sparse.c
index 4900707ae146cf73c1c9ca4d01bd63a9dfc27c8b..7a5dacaa06e3f277c8543c502dba0e3c6a6a1a13 100644 (file)
@@ -23,8 +23,7 @@
  * 1) mem_section      - memory sections, mem_map's for valid memory
  */
 #ifdef CONFIG_SPARSEMEM_EXTREME
-struct mem_section *mem_section[NR_SECTION_ROOTS]
-       ____cacheline_internodealigned_in_smp;
+struct mem_section **mem_section;
 #else
 struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT]
        ____cacheline_internodealigned_in_smp;
@@ -101,7 +100,7 @@ static inline int sparse_index_init(unsigned long section_nr, int nid)
 int __section_nr(struct mem_section* ms)
 {
        unsigned long root_nr;
-       struct mem_section* root;
+       struct mem_section *root = NULL;
 
        for (root_nr = 0; root_nr < NR_SECTION_ROOTS; root_nr++) {
                root = __nr_to_section(root_nr * SECTIONS_PER_ROOT);
@@ -112,7 +111,7 @@ int __section_nr(struct mem_section* ms)
                     break;
        }
 
-       VM_BUG_ON(root_nr == NR_SECTION_ROOTS);
+       VM_BUG_ON(!root);
 
        return (root_nr * SECTIONS_PER_ROOT) + (ms - root);
 }
@@ -208,6 +207,16 @@ void __init memory_present(int nid, unsigned long start, unsigned long end)
 {
        unsigned long pfn;
 
+#ifdef CONFIG_SPARSEMEM_EXTREME
+       if (unlikely(!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
+
        start &= PAGE_SECTION_MASK;
        mminit_validate_memmodel_limits(&start, &end);
        for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {
@@ -330,11 +339,17 @@ again:
 static void __init check_usemap_section_nr(int nid, unsigned long *usemap)
 {
        unsigned long usemap_snr, pgdat_snr;
-       static unsigned long old_usemap_snr = NR_MEM_SECTIONS;
-       static unsigned long old_pgdat_snr = NR_MEM_SECTIONS;
+       static unsigned long old_usemap_snr;
+       static unsigned long old_pgdat_snr;
        struct pglist_data *pgdat = NODE_DATA(nid);
        int usemap_nid;
 
+       /* First call */
+       if (!old_usemap_snr) {
+               old_usemap_snr = NR_MEM_SECTIONS;
+               old_pgdat_snr = NR_MEM_SECTIONS;
+       }
+
        usemap_snr = pfn_to_section_nr(__pa(usemap) >> PAGE_SHIFT);
        pgdat_snr = pfn_to_section_nr(__pa(pgdat) >> PAGE_SHIFT);
        if (usemap_snr == pgdat_snr)
@@ -438,9 +453,9 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
        }
 
        size = PAGE_ALIGN(size);
-       map = memblock_virt_alloc_try_nid(size * map_count,
-                                         PAGE_SIZE, __pa(MAX_DMA_ADDRESS),
-                                         BOOTMEM_ALLOC_ACCESSIBLE, nodeid);
+       map = memblock_virt_alloc_try_nid_raw(size * map_count,
+                                             PAGE_SIZE, __pa(MAX_DMA_ADDRESS),
+                                             BOOTMEM_ALLOC_ACCESSIBLE, nodeid);
        if (map) {
                for (pnum = pnum_begin; pnum < pnum_end; pnum++) {
                        if (!present_section_nr(pnum))