diff options
Diffstat (limited to 'arch/x86_64/kernel/smpboot.c')
-rw-r--r-- | arch/x86_64/kernel/smpboot.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 571a55462fa0..b969ee128728 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -508,9 +508,22 @@ void __cpuinit start_secondary(void) | |||
508 | set_cpu_sibling_map(smp_processor_id()); | 508 | set_cpu_sibling_map(smp_processor_id()); |
509 | 509 | ||
510 | /* | 510 | /* |
511 | * We need to hold call_lock, so there is no inconsistency | ||
512 | * between the time smp_call_function() determines number of | ||
513 | * IPI receipients, and the time when the determination is made | ||
514 | * for which cpus receive the IPI in genapic_flat.c. Holding this | ||
515 | * lock helps us to not include this cpu in a currently in progress | ||
516 | * smp_call_function(). | ||
517 | */ | ||
518 | lock_ipi_call_lock(); | ||
519 | |||
520 | /* | ||
511 | * Allow the master to continue. | 521 | * Allow the master to continue. |
512 | */ | 522 | */ |
513 | cpu_set(smp_processor_id(), cpu_online_map); | 523 | cpu_set(smp_processor_id(), cpu_online_map); |
524 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | ||
525 | unlock_ipi_call_lock(); | ||
526 | |||
514 | mb(); | 527 | mb(); |
515 | 528 | ||
516 | /* Wait for TSC sync to not schedule things before. | 529 | /* Wait for TSC sync to not schedule things before. |
@@ -1038,6 +1051,7 @@ void __init smp_prepare_boot_cpu(void) | |||
1038 | cpu_set(me, cpu_callout_map); | 1051 | cpu_set(me, cpu_callout_map); |
1039 | cpu_set(0, cpu_sibling_map[0]); | 1052 | cpu_set(0, cpu_sibling_map[0]); |
1040 | cpu_set(0, cpu_core_map[0]); | 1053 | cpu_set(0, cpu_core_map[0]); |
1054 | per_cpu(cpu_state, me) = CPU_ONLINE; | ||
1041 | } | 1055 | } |
1042 | 1056 | ||
1043 | /* | 1057 | /* |
@@ -1066,6 +1080,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
1066 | return -ENOSYS; | 1080 | return -ENOSYS; |
1067 | } | 1081 | } |
1068 | 1082 | ||
1083 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | ||
1069 | /* Boot it! */ | 1084 | /* Boot it! */ |
1070 | err = do_boot_cpu(cpu, apicid); | 1085 | err = do_boot_cpu(cpu, apicid); |
1071 | if (err < 0) { | 1086 | if (err < 0) { |
@@ -1170,8 +1185,10 @@ void __cpu_die(unsigned int cpu) | |||
1170 | 1185 | ||
1171 | for (i = 0; i < 10; i++) { | 1186 | for (i = 0; i < 10; i++) { |
1172 | /* They ack this in play_dead by setting CPU_DEAD */ | 1187 | /* They ack this in play_dead by setting CPU_DEAD */ |
1173 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) | 1188 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) { |
1189 | printk ("CPU %d is now offline\n", cpu); | ||
1174 | return; | 1190 | return; |
1191 | } | ||
1175 | current->state = TASK_UNINTERRUPTIBLE; | 1192 | current->state = TASK_UNINTERRUPTIBLE; |
1176 | schedule_timeout(HZ/10); | 1193 | schedule_timeout(HZ/10); |
1177 | } | 1194 | } |