aboutsummaryrefslogtreecommitdiffstats
path: root/mm/sparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/sparse.c')
-rw-r--r--mm/sparse.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/mm/sparse.c b/mm/sparse.c
index 98d6b39c3472..458109b99e61 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -304,22 +304,48 @@ void __init sparse_init(void)
304 unsigned long pnum; 304 unsigned long pnum;
305 struct page *map; 305 struct page *map;
306 unsigned long *usemap; 306 unsigned long *usemap;
307 unsigned long **usemap_map;
308 int size;
309
310 /*
311 * map is using big page (aka 2M in x86 64 bit)
312 * usemap is less one page (aka 24 bytes)
313 * so alloc 2M (with 2M align) and 24 bytes in turn will
314 * make next 2M slip to one more 2M later.
315 * then in big system, the memory will have a lot of holes...
316 * here try to allocate 2M pages continously.
317 *
318 * powerpc need to call sparse_init_one_section right after each
319 * sparse_early_mem_map_alloc, so allocate usemap_map at first.
320 */
321 size = sizeof(unsigned long *) * NR_MEM_SECTIONS;
322 usemap_map = alloc_bootmem(size);
323 if (!usemap_map)
324 panic("can not allocate usemap_map\n");
307 325
308 for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) { 326 for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
309 if (!present_section_nr(pnum)) 327 if (!present_section_nr(pnum))
310 continue; 328 continue;
329 usemap_map[pnum] = sparse_early_usemap_alloc(pnum);
330 }
311 331
312 map = sparse_early_mem_map_alloc(pnum); 332 for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
313 if (!map) 333 if (!present_section_nr(pnum))
314 continue; 334 continue;
315 335
316 usemap = sparse_early_usemap_alloc(pnum); 336 usemap = usemap_map[pnum];
317 if (!usemap) 337 if (!usemap)
318 continue; 338 continue;
319 339
340 map = sparse_early_mem_map_alloc(pnum);
341 if (!map)
342 continue;
343
320 sparse_init_one_section(__nr_to_section(pnum), pnum, map, 344 sparse_init_one_section(__nr_to_section(pnum), pnum, map,
321 usemap); 345 usemap);
322 } 346 }
347
348 free_bootmem(__pa(usemap_map), size);
323} 349}
324 350
325#ifdef CONFIG_MEMORY_HOTPLUG 351#ifdef CONFIG_MEMORY_HOTPLUG