diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/mm/numa_64.c | 94 |
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 | */ | ||
565 | static int __init dummy_numa_init(void) | 574 | static 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 | ||
578 | void __init initmem_init(void) | 587 | static 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++) { | 627 | void __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 | ||
631 | unsigned long __init numa_free_all_bootmem(void) | 647 | unsigned long __init numa_free_all_bootmem(void) |