diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-08 05:59:23 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 05:59:23 -0400 |
commit | 2b4fa851b2f06fdb04cac808b57324f5e51e1578 (patch) | |
tree | 97db3ad5adda7683923630982f68b8b52c86e790 /arch/x86/kernel/smpboot.c | |
parent | 3de352bbd86f890dd0c5e1c09a6a1b0b29e0f8ce (diff) | |
parent | 46f68e1c6b04a04772e828ff3bcd07ed708805c2 (diff) |
Merge branch 'x86/numa' into x86/devel
Conflicts:
arch/x86/Kconfig
arch/x86/kernel/e820.c
arch/x86/kernel/efi_64.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_32.c
arch/x86/mm/init_64.c
include/asm-x86/proto.h
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 6be701f3027f..ae0a7a200421 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -67,22 +67,6 @@ | |||
67 | #include <mach_wakecpu.h> | 67 | #include <mach_wakecpu.h> |
68 | #include <smpboot_hooks.h> | 68 | #include <smpboot_hooks.h> |
69 | 69 | ||
70 | /* | ||
71 | * FIXME: For x86_64, those are defined in other files. But moving them here, | ||
72 | * would make the setup areas dependent on smp, which is a loss. When we | ||
73 | * integrate apic between arches, we can probably do a better job, but | ||
74 | * right now, they'll stay here -- glommer | ||
75 | */ | ||
76 | |||
77 | /* which logical CPU number maps to which CPU (physical APIC ID) */ | ||
78 | u16 x86_cpu_to_apicid_init[NR_CPUS] __initdata = | ||
79 | { [0 ... NR_CPUS-1] = BAD_APICID }; | ||
80 | void *x86_cpu_to_apicid_early_ptr; | ||
81 | |||
82 | u16 x86_bios_cpu_apicid_init[NR_CPUS] __initdata | ||
83 | = { [0 ... NR_CPUS-1] = BAD_APICID }; | ||
84 | void *x86_bios_cpu_apicid_early_ptr; | ||
85 | |||
86 | #ifdef CONFIG_X86_32 | 70 | #ifdef CONFIG_X86_32 |
87 | u8 apicid_2_node[MAX_APICID]; | 71 | u8 apicid_2_node[MAX_APICID]; |
88 | static int low_mappings; | 72 | static int low_mappings; |
@@ -814,6 +798,45 @@ static void __cpuinit do_fork_idle(struct work_struct *work) | |||
814 | complete(&c_idle->done); | 798 | complete(&c_idle->done); |
815 | } | 799 | } |
816 | 800 | ||
801 | #ifdef CONFIG_X86_64 | ||
802 | /* | ||
803 | * Allocate node local memory for the AP pda. | ||
804 | * | ||
805 | * Must be called after the _cpu_pda pointer table is initialized. | ||
806 | */ | ||
807 | static int __cpuinit get_local_pda(int cpu) | ||
808 | { | ||
809 | struct x8664_pda *oldpda, *newpda; | ||
810 | unsigned long size = sizeof(struct x8664_pda); | ||
811 | int node = cpu_to_node(cpu); | ||
812 | |||
813 | if (cpu_pda(cpu) && !cpu_pda(cpu)->in_bootmem) | ||
814 | return 0; | ||
815 | |||
816 | oldpda = cpu_pda(cpu); | ||
817 | newpda = kmalloc_node(size, GFP_ATOMIC, node); | ||
818 | if (!newpda) { | ||
819 | printk(KERN_ERR "Could not allocate node local PDA " | ||
820 | "for CPU %d on node %d\n", cpu, node); | ||
821 | |||
822 | if (oldpda) | ||
823 | return 0; /* have a usable pda */ | ||
824 | else | ||
825 | return -1; | ||
826 | } | ||
827 | |||
828 | if (oldpda) { | ||
829 | memcpy(newpda, oldpda, size); | ||
830 | if (!after_bootmem) | ||
831 | free_bootmem((unsigned long)oldpda, size); | ||
832 | } | ||
833 | |||
834 | newpda->in_bootmem = 0; | ||
835 | cpu_pda(cpu) = newpda; | ||
836 | return 0; | ||
837 | } | ||
838 | #endif /* CONFIG_X86_64 */ | ||
839 | |||
817 | static int __cpuinit do_boot_cpu(int apicid, int cpu) | 840 | static int __cpuinit do_boot_cpu(int apicid, int cpu) |
818 | /* | 841 | /* |
819 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad | 842 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad |
@@ -839,19 +862,11 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
839 | } | 862 | } |
840 | 863 | ||
841 | /* Allocate node local memory for AP pdas */ | 864 | /* Allocate node local memory for AP pdas */ |
842 | if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) { | 865 | if (cpu > 0) { |
843 | struct x8664_pda *newpda, *pda; | 866 | boot_error = get_local_pda(cpu); |
844 | int node = cpu_to_node(cpu); | 867 | if (boot_error) |
845 | pda = cpu_pda(cpu); | 868 | goto restore_state; |
846 | newpda = kmalloc_node(sizeof(struct x8664_pda), GFP_ATOMIC, | 869 | /* if can't get pda memory, can't start cpu */ |
847 | node); | ||
848 | if (newpda) { | ||
849 | memcpy(newpda, pda, sizeof(struct x8664_pda)); | ||
850 | cpu_pda(cpu) = newpda; | ||
851 | } else | ||
852 | printk(KERN_ERR | ||
853 | "Could not allocate node local PDA for CPU %d on node %d\n", | ||
854 | cpu, node); | ||
855 | } | 870 | } |
856 | #endif | 871 | #endif |
857 | 872 | ||
@@ -970,11 +985,13 @@ do_rest: | |||
970 | } | 985 | } |
971 | } | 986 | } |
972 | 987 | ||
988 | restore_state: | ||
989 | |||
973 | if (boot_error) { | 990 | if (boot_error) { |
974 | /* Try to put things back the way they were before ... */ | 991 | /* Try to put things back the way they were before ... */ |
975 | unmap_cpu_to_logical_apicid(cpu); | 992 | unmap_cpu_to_logical_apicid(cpu); |
976 | #ifdef CONFIG_X86_64 | 993 | #ifdef CONFIG_X86_64 |
977 | clear_node_cpumask(cpu); /* was set by numa_add_cpu */ | 994 | numa_remove_cpu(cpu); /* was set by numa_add_cpu */ |
978 | #endif | 995 | #endif |
979 | cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */ | 996 | cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */ |
980 | cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ | 997 | cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ |
@@ -1347,6 +1364,8 @@ __init void prefill_possible_map(void) | |||
1347 | 1364 | ||
1348 | for (i = 0; i < possible; i++) | 1365 | for (i = 0; i < possible; i++) |
1349 | cpu_set(i, cpu_possible_map); | 1366 | cpu_set(i, cpu_possible_map); |
1367 | |||
1368 | nr_cpu_ids = possible; | ||
1350 | } | 1369 | } |
1351 | 1370 | ||
1352 | static void __ref remove_cpu_from_maps(int cpu) | 1371 | static void __ref remove_cpu_from_maps(int cpu) |
@@ -1357,7 +1376,7 @@ static void __ref remove_cpu_from_maps(int cpu) | |||
1357 | cpu_clear(cpu, cpu_callin_map); | 1376 | cpu_clear(cpu, cpu_callin_map); |
1358 | /* was set by cpu_init() */ | 1377 | /* was set by cpu_init() */ |
1359 | clear_bit(cpu, (unsigned long *)&cpu_initialized); | 1378 | clear_bit(cpu, (unsigned long *)&cpu_initialized); |
1360 | clear_node_cpumask(cpu); | 1379 | numa_remove_cpu(cpu); |
1361 | #endif | 1380 | #endif |
1362 | } | 1381 | } |
1363 | 1382 | ||