summaryrefslogtreecommitdiffstats
path: root/mm/sparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/sparse.c')
-rw-r--r--mm/sparse.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/mm/sparse.c b/mm/sparse.c
index eb188eb6b82d..2ea8b3dbd0df 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -381,6 +381,7 @@ static void __init sparse_early_usemaps_alloc_node(void *data,
381 unsigned long pnum; 381 unsigned long pnum;
382 unsigned long **usemap_map = (unsigned long **)data; 382 unsigned long **usemap_map = (unsigned long **)data;
383 int size = usemap_size(); 383 int size = usemap_size();
384 int nr_consumed_maps = 0;
384 385
385 usemap = sparse_early_usemaps_alloc_pgdat_section(NODE_DATA(nodeid), 386 usemap = sparse_early_usemaps_alloc_pgdat_section(NODE_DATA(nodeid),
386 size * usemap_count); 387 size * usemap_count);
@@ -392,9 +393,10 @@ static void __init sparse_early_usemaps_alloc_node(void *data,
392 for (pnum = pnum_begin; pnum < pnum_end; pnum++) { 393 for (pnum = pnum_begin; pnum < pnum_end; pnum++) {
393 if (!present_section_nr(pnum)) 394 if (!present_section_nr(pnum))
394 continue; 395 continue;
395 usemap_map[pnum] = usemap; 396 usemap_map[nr_consumed_maps] = usemap;
396 usemap += size; 397 usemap += size;
397 check_usemap_section_nr(nodeid, usemap_map[pnum]); 398 check_usemap_section_nr(nodeid, usemap_map[nr_consumed_maps]);
399 nr_consumed_maps++;
398 } 400 }
399} 401}
400 402
@@ -419,29 +421,34 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
419 void *map; 421 void *map;
420 unsigned long pnum; 422 unsigned long pnum;
421 unsigned long size = sizeof(struct page) * PAGES_PER_SECTION; 423 unsigned long size = sizeof(struct page) * PAGES_PER_SECTION;
424 int nr_consumed_maps;
422 425
423 size = PAGE_ALIGN(size); 426 size = PAGE_ALIGN(size);
424 map = memblock_virt_alloc_try_nid_raw(size * map_count, 427 map = memblock_virt_alloc_try_nid_raw(size * map_count,
425 PAGE_SIZE, __pa(MAX_DMA_ADDRESS), 428 PAGE_SIZE, __pa(MAX_DMA_ADDRESS),
426 BOOTMEM_ALLOC_ACCESSIBLE, nodeid); 429 BOOTMEM_ALLOC_ACCESSIBLE, nodeid);
427 if (map) { 430 if (map) {
431 nr_consumed_maps = 0;
428 for (pnum = pnum_begin; pnum < pnum_end; pnum++) { 432 for (pnum = pnum_begin; pnum < pnum_end; pnum++) {
429 if (!present_section_nr(pnum)) 433 if (!present_section_nr(pnum))
430 continue; 434 continue;
431 map_map[pnum] = map; 435 map_map[nr_consumed_maps] = map;
432 map += size; 436 map += size;
437 nr_consumed_maps++;
433 } 438 }
434 return; 439 return;
435 } 440 }
436 441
437 /* fallback */ 442 /* fallback */
443 nr_consumed_maps = 0;
438 for (pnum = pnum_begin; pnum < pnum_end; pnum++) { 444 for (pnum = pnum_begin; pnum < pnum_end; pnum++) {
439 struct mem_section *ms; 445 struct mem_section *ms;
440 446
441 if (!present_section_nr(pnum)) 447 if (!present_section_nr(pnum))
442 continue; 448 continue;
443 map_map[pnum] = sparse_mem_map_populate(pnum, nodeid, NULL); 449 map_map[nr_consumed_maps] =
444 if (map_map[pnum]) 450 sparse_mem_map_populate(pnum, nodeid, NULL);
451 if (map_map[nr_consumed_maps++])
445 continue; 452 continue;
446 ms = __nr_to_section(pnum); 453 ms = __nr_to_section(pnum);
447 pr_err("%s: sparsemem memory map backing failed some memory will not be available\n", 454 pr_err("%s: sparsemem memory map backing failed some memory will not be available\n",
@@ -521,6 +528,7 @@ static void __init alloc_usemap_and_memmap(void (*alloc_func)
521 /* new start, update count etc*/ 528 /* new start, update count etc*/
522 nodeid_begin = nodeid; 529 nodeid_begin = nodeid;
523 pnum_begin = pnum; 530 pnum_begin = pnum;
531 data += map_count * data_unit_size;
524 map_count = 1; 532 map_count = 1;
525 } 533 }
526 /* ok, last chunk */ 534 /* ok, last chunk */
@@ -539,6 +547,7 @@ void __init sparse_init(void)
539 unsigned long *usemap; 547 unsigned long *usemap;
540 unsigned long **usemap_map; 548 unsigned long **usemap_map;
541 int size; 549 int size;
550 int nr_consumed_maps = 0;
542#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER 551#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER
543 int size2; 552 int size2;
544 struct page **map_map; 553 struct page **map_map;
@@ -561,7 +570,7 @@ void __init sparse_init(void)
561 * powerpc need to call sparse_init_one_section right after each 570 * powerpc need to call sparse_init_one_section right after each
562 * sparse_early_mem_map_alloc, so allocate usemap_map at first. 571 * sparse_early_mem_map_alloc, so allocate usemap_map at first.
563 */ 572 */
564 size = sizeof(unsigned long *) * NR_MEM_SECTIONS; 573 size = sizeof(unsigned long *) * nr_present_sections;
565 usemap_map = memblock_virt_alloc(size, 0); 574 usemap_map = memblock_virt_alloc(size, 0);
566 if (!usemap_map) 575 if (!usemap_map)
567 panic("can not allocate usemap_map\n"); 576 panic("can not allocate usemap_map\n");
@@ -570,7 +579,7 @@ void __init sparse_init(void)
570 sizeof(usemap_map[0])); 579 sizeof(usemap_map[0]));
571 580
572#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER 581#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER
573 size2 = sizeof(struct page *) * NR_MEM_SECTIONS; 582 size2 = sizeof(struct page *) * nr_present_sections;
574 map_map = memblock_virt_alloc(size2, 0); 583 map_map = memblock_virt_alloc(size2, 0);
575 if (!map_map) 584 if (!map_map)
576 panic("can not allocate map_map\n"); 585 panic("can not allocate map_map\n");
@@ -579,27 +588,46 @@ void __init sparse_init(void)
579 sizeof(map_map[0])); 588 sizeof(map_map[0]));
580#endif 589#endif
581 590
591 /*
592 * The number of present sections stored in nr_present_sections
593 * are kept the same since mem sections are marked as present in
594 * memory_present(). In this for loop, we need check which sections
595 * failed to allocate memmap or usemap, then clear its
596 * ->section_mem_map accordingly. During this process, we need
597 * increase 'nr_consumed_maps' whether its allocation of memmap
598 * or usemap failed or not, so that after we handle the i-th
599 * memory section, can get memmap and usemap of (i+1)-th section
600 * correctly.
601 */
582 for_each_present_section_nr(0, pnum) { 602 for_each_present_section_nr(0, pnum) {
583 struct mem_section *ms; 603 struct mem_section *ms;
604
605 if (nr_consumed_maps >= nr_present_sections) {
606 pr_err("nr_consumed_maps goes beyond nr_present_sections\n");
607 break;
608 }
584 ms = __nr_to_section(pnum); 609 ms = __nr_to_section(pnum);
585 usemap = usemap_map[pnum]; 610 usemap = usemap_map[nr_consumed_maps];
586 if (!usemap) { 611 if (!usemap) {
587 ms->section_mem_map = 0; 612 ms->section_mem_map = 0;
613 nr_consumed_maps++;
588 continue; 614 continue;
589 } 615 }
590 616
591#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER 617#ifdef CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER
592 map = map_map[pnum]; 618 map = map_map[nr_consumed_maps];
593#else 619#else
594 map = sparse_early_mem_map_alloc(pnum); 620 map = sparse_early_mem_map_alloc(pnum);
595#endif 621#endif
596 if (!map) { 622 if (!map) {
597 ms->section_mem_map = 0; 623 ms->section_mem_map = 0;
624 nr_consumed_maps++;
598 continue; 625 continue;
599 } 626 }
600 627
601 sparse_init_one_section(__nr_to_section(pnum), pnum, map, 628 sparse_init_one_section(__nr_to_section(pnum), pnum, map,
602 usemap); 629 usemap);
630 nr_consumed_maps++;
603 } 631 }
604 632
605 vmemmap_populate_print_last(); 633 vmemmap_populate_print_last();