aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/mm/numa_64.c94
1 files changed, 55 insertions, 39 deletions
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 86491ba568d9..9ec0f209a6a4 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -562,6 +562,15 @@ static int __init numa_register_memblks(struct numa_meminfo *mi)
562 return 0; 562 return 0;
563} 563}
564 564
565/**
566 * dummy_numma_init - Fallback dummy NUMA init
567 *
568 * Used if there's no underlying NUMA architecture, NUMA initialization
569 * fails, or NUMA is disabled on the command line.
570 *
571 * Must online at least one node and add memory blocks that cover all
572 * allowed memory. This function must not fail.
573 */
565static int __init dummy_numa_init(void) 574static int __init dummy_numa_init(void)
566{ 575{
567 printk(KERN_INFO "%s\n", 576 printk(KERN_INFO "%s\n",
@@ -575,57 +584,64 @@ static int __init dummy_numa_init(void)
575 return 0; 584 return 0;
576} 585}
577 586
578void __init initmem_init(void) 587static int __init numa_init(int (*init_func)(void))
579{ 588{
580 int (*numa_init[])(void) = { [2] = dummy_numa_init }; 589 int i;
581 int i, j; 590 int ret;
582
583 if (!numa_off) {
584#ifdef CONFIG_ACPI_NUMA
585 numa_init[0] = x86_acpi_numa_init;
586#endif
587#ifdef CONFIG_AMD_NUMA
588 numa_init[1] = amd_numa_init;
589#endif
590 }
591 591
592 for (i = 0; i < ARRAY_SIZE(numa_init); i++) { 592 for (i = 0; i < MAX_LOCAL_APIC; i++)
593 if (!numa_init[i]) 593 set_apicid_to_node(i, NUMA_NO_NODE);
594 continue;
595 594
596 for (j = 0; j < MAX_LOCAL_APIC; j++) 595 nodes_clear(numa_nodes_parsed);
597 set_apicid_to_node(j, NUMA_NO_NODE); 596 nodes_clear(node_possible_map);
597 nodes_clear(node_online_map);
598 memset(&numa_meminfo, 0, sizeof(numa_meminfo));
599 remove_all_active_ranges();
600 numa_reset_distance();
598 601
599 nodes_clear(numa_nodes_parsed); 602 ret = init_func();
600 nodes_clear(node_possible_map); 603 if (ret < 0)
601 nodes_clear(node_online_map); 604 return ret;
602 memset(&numa_meminfo, 0, sizeof(numa_meminfo)); 605 ret = numa_cleanup_meminfo(&numa_meminfo);
603 remove_all_active_ranges(); 606 if (ret < 0)
604 numa_reset_distance(); 607 return ret;
605 608
606 if (numa_init[i]() < 0) 609 numa_emulation(&numa_meminfo, numa_distance_cnt);
607 continue;
608 610
609 if (numa_cleanup_meminfo(&numa_meminfo) < 0) 611 ret = numa_register_memblks(&numa_meminfo);
610 continue; 612 if (ret < 0)
613 return ret;
611 614
612 numa_emulation(&numa_meminfo, numa_distance_cnt); 615 for (i = 0; i < nr_cpu_ids; i++) {
616 int nid = early_cpu_to_node(i);
613 617
614 if (numa_register_memblks(&numa_meminfo) < 0) 618 if (nid == NUMA_NO_NODE)
615 continue; 619 continue;
620 if (!node_online(nid))
621 numa_clear_node(i);
622 }
623 numa_init_array();
624 return 0;
625}
616 626
617 for (j = 0; j < nr_cpu_ids; j++) { 627void __init initmem_init(void)
618 int nid = early_cpu_to_node(j); 628{
629 int ret;
619 630
620 if (nid == NUMA_NO_NODE) 631 if (!numa_off) {
621 continue; 632#ifdef CONFIG_ACPI_NUMA
622 if (!node_online(nid)) 633 ret = numa_init(x86_acpi_numa_init);
623 numa_clear_node(j); 634 if (!ret)
624 } 635 return;
625 numa_init_array(); 636#endif
626 return; 637#ifdef CONFIG_AMD_NUMA
638 ret = numa_init(amd_numa_init);
639 if (!ret)
640 return;
641#endif
627 } 642 }
628 BUG(); 643
644 numa_init(dummy_numa_init);
629} 645}
630 646
631unsigned long __init numa_free_all_bootmem(void) 647unsigned long __init numa_free_all_bootmem(void)