aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/smpboot.c
diff options
context:
space:
mode:
authorAshok Raj <ashok.raj@intel.com>2005-06-25 17:55:02 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 19:24:31 -0400
commit884d9e40b4089014f40c49e86ac6505842db2b53 (patch)
tree8ff4f3225b46f84a5973074d9c4792b9e744c8e1 /arch/x86_64/kernel/smpboot.c
parentcb0cd8d49a9b81aff7a02e2ed826b5cfdfe9a172 (diff)
[PATCH] x86_64: Dont use broadcast shortcut to make it cpu hotplug safe.
Broadcast IPI's provide un-expected behaviour for cpu hotplug. CPU's in offline state also end up receiving the IPI. Once the cpus become online they receive these stale IPI's which are bad and introduce unexpected behaviour. This is easily avoided by not sending a broadcast and addressing just the CPU's in online map. Doing prelim cycle counts it appears there is no big overhead and numbers seem around 0x3000-0x3900 on an average on x86 and x86_64 systems with CPUS running 3G, both for broadcast and mask version of the API's. The shortcuts are useful only for flat mode (where the perf shows no degradation), and in cluster mode, its unicast anyway. Its simpler to just not use broadcast anymore. Signed-off-by: Ashok Raj <ashok.raj@intel.com> Acked-by: Andi Kleen <ak@muc.de> Acked-by: Zwane Mwaikambo <zwane@arm.linux.org.uk> Signed-off-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/smpboot.c')
-rw-r--r--arch/x86_64/kernel/smpboot.c19
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 }