|
@@ -304,22 +304,48 @@ void __init sparse_init(void)
|
|
|
unsigned long pnum;
|
|
|
struct page *map;
|
|
|
unsigned long *usemap;
|
|
|
+ unsigned long **usemap_map;
|
|
|
+ int size;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * map is using big page (aka 2M in x86 64 bit)
|
|
|
+ * usemap is less one page (aka 24 bytes)
|
|
|
+ * so alloc 2M (with 2M align) and 24 bytes in turn will
|
|
|
+ * make next 2M slip to one more 2M later.
|
|
|
+ * then in big system, the memory will have a lot of holes...
|
|
|
+ * here try to allocate 2M pages continously.
|
|
|
+ *
|
|
|
+ * powerpc need to call sparse_init_one_section right after each
|
|
|
+ * sparse_early_mem_map_alloc, so allocate usemap_map at first.
|
|
|
+ */
|
|
|
+ size = sizeof(unsigned long *) * NR_MEM_SECTIONS;
|
|
|
+ usemap_map = alloc_bootmem(size);
|
|
|
+ if (!usemap_map)
|
|
|
+ panic("can not allocate usemap_map\n");
|
|
|
|
|
|
for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
|
|
|
if (!present_section_nr(pnum))
|
|
|
continue;
|
|
|
+ usemap_map[pnum] = sparse_early_usemap_alloc(pnum);
|
|
|
+ }
|
|
|
|
|
|
- map = sparse_early_mem_map_alloc(pnum);
|
|
|
- if (!map)
|
|
|
+ for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
|
|
|
+ if (!present_section_nr(pnum))
|
|
|
continue;
|
|
|
|
|
|
- usemap = sparse_early_usemap_alloc(pnum);
|
|
|
+ usemap = usemap_map[pnum];
|
|
|
if (!usemap)
|
|
|
continue;
|
|
|
|
|
|
+ map = sparse_early_mem_map_alloc(pnum);
|
|
|
+ if (!map)
|
|
|
+ continue;
|
|
|
+
|
|
|
sparse_init_one_section(__nr_to_section(pnum), pnum, map,
|
|
|
usemap);
|
|
|
}
|
|
|
+
|
|
|
+ free_bootmem(__pa(usemap_map), size);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_MEMORY_HOTPLUG
|