aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/smpboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/smpboot.c')
-rw-r--r--arch/i386/kernel/smpboot.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 4c470e99a742..82371d83bfa9 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -1003,7 +1003,6 @@ void cpu_exit_clear(void)
1003 1003
1004 cpu_clear(cpu, cpu_callout_map); 1004 cpu_clear(cpu, cpu_callout_map);
1005 cpu_clear(cpu, cpu_callin_map); 1005 cpu_clear(cpu, cpu_callin_map);
1006 cpu_clear(cpu, cpu_present_map);
1007 1006
1008 cpu_clear(cpu, smp_commenced_mask); 1007 cpu_clear(cpu, smp_commenced_mask);
1009 unmap_cpu_to_logical_apicid(cpu); 1008 unmap_cpu_to_logical_apicid(cpu);
@@ -1015,31 +1014,20 @@ struct warm_boot_cpu_info {
1015 int cpu; 1014 int cpu;
1016}; 1015};
1017 1016
1018static void __devinit do_warm_boot_cpu(void *p) 1017static void __cpuinit do_warm_boot_cpu(void *p)
1019{ 1018{
1020 struct warm_boot_cpu_info *info = p; 1019 struct warm_boot_cpu_info *info = p;
1021 do_boot_cpu(info->apicid, info->cpu); 1020 do_boot_cpu(info->apicid, info->cpu);
1022 complete(info->complete); 1021 complete(info->complete);
1023} 1022}
1024 1023
1025int __devinit smp_prepare_cpu(int cpu) 1024static int __cpuinit __smp_prepare_cpu(int cpu)
1026{ 1025{
1027 DECLARE_COMPLETION(done); 1026 DECLARE_COMPLETION(done);
1028 struct warm_boot_cpu_info info; 1027 struct warm_boot_cpu_info info;
1029 struct work_struct task; 1028 struct work_struct task;
1030 int apicid, ret; 1029 int apicid, ret;
1031 1030
1032 lock_cpu_hotplug();
1033
1034 /*
1035 * On x86, CPU0 is never offlined. Trying to bring up an
1036 * already-booted CPU will hang. So check for that case.
1037 */
1038 if (cpu_online(cpu)) {
1039 ret = -EINVAL;
1040 goto exit;
1041 }
1042
1043 apicid = x86_cpu_to_apicid[cpu]; 1031 apicid = x86_cpu_to_apicid[cpu];
1044 if (apicid == BAD_APICID) { 1032 if (apicid == BAD_APICID) {
1045 ret = -ENODEV; 1033 ret = -ENODEV;
@@ -1064,7 +1052,6 @@ int __devinit smp_prepare_cpu(int cpu)
1064 zap_low_mappings(); 1052 zap_low_mappings();
1065 ret = 0; 1053 ret = 0;
1066exit: 1054exit:
1067 unlock_cpu_hotplug();
1068 return ret; 1055 return ret;
1069} 1056}
1070#endif 1057#endif
@@ -1392,6 +1379,22 @@ void __cpu_die(unsigned int cpu)
1392 1379
1393int __devinit __cpu_up(unsigned int cpu) 1380int __devinit __cpu_up(unsigned int cpu)
1394{ 1381{
1382#ifdef CONFIG_HOTPLUG_CPU
1383 int ret=0;
1384
1385 /*
1386 * We do warm boot only on cpus that had booted earlier
1387 * Otherwise cold boot is all handled from smp_boot_cpus().
1388 * cpu_callin_map is set during AP kickstart process. Its reset
1389 * when a cpu is taken offline from cpu_exit_clear().
1390 */
1391 if (!cpu_isset(cpu, cpu_callin_map))
1392 ret = __smp_prepare_cpu(cpu);
1393
1394 if (ret)
1395 return -EIO;
1396#endif
1397
1395 /* In case one didn't come up */ 1398 /* In case one didn't come up */
1396 if (!cpu_isset(cpu, cpu_callin_map)) { 1399 if (!cpu_isset(cpu, cpu_callin_map)) {
1397 printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); 1400 printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);