aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-08 05:59:23 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-08 05:59:23 -0400
commit2b4fa851b2f06fdb04cac808b57324f5e51e1578 (patch)
tree97db3ad5adda7683923630982f68b8b52c86e790 /arch/x86/kernel/smpboot.c
parent3de352bbd86f890dd0c5e1c09a6a1b0b29e0f8ce (diff)
parent46f68e1c6b04a04772e828ff3bcd07ed708805c2 (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.c81
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) */
78u16 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
79 { [0 ... NR_CPUS-1] = BAD_APICID };
80void *x86_cpu_to_apicid_early_ptr;
81
82u16 x86_bios_cpu_apicid_init[NR_CPUS] __initdata
83 = { [0 ... NR_CPUS-1] = BAD_APICID };
84void *x86_bios_cpu_apicid_early_ptr;
85
86#ifdef CONFIG_X86_32 70#ifdef CONFIG_X86_32
87u8 apicid_2_node[MAX_APICID]; 71u8 apicid_2_node[MAX_APICID];
88static int low_mappings; 72static 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 */
807static 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
817static int __cpuinit do_boot_cpu(int apicid, int cpu) 840static 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
988restore_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
1352static void __ref remove_cpu_from_maps(int cpu) 1371static 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