aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/smpboot.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-24 19:00:23 -0400
committerAndi Kleen <andi@one.(none)>2006-10-24 19:00:23 -0400
commit70a0a5357db20c291d46c04011d646d5d84c868c (patch)
treefb82087c685b2f3018172a5956f86cc36fc833d1 /arch/x86_64/kernel/smpboot.c
parentd1752aa884ec0ac3027c1a3d456bf69bf765c8b8 (diff)
[PATCH] x86-64: Only look at per_cpu data for online cpus.
When I generalized __assign_irq_vector I failed to pay attention to what happens when you access a per cpu data structure for a cpu that is not online. It is an undefined case making any code that does it have undefined behavior as well. The code still needs to be able to allocate a vector across cpus that are not online to properly handle combinations like lowest priority interrupt delivery and cpu_hotplug. Not that we can do that today but the infrastructure shouldn't prevent it. So this patch updates the places where we touch per cpu data to only touch online cpus, it makes cpu vector allocation an atomic operation with respect to cpu hotplug, and it updates the cpu start code to properly initialize vector_irq so we don't have inconsistencies. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/kernel/smpboot.c')
-rw-r--r--arch/x86_64/kernel/smpboot.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 7b7a6870288a..62c2e747af58 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -581,12 +581,16 @@ void __cpuinit start_secondary(void)
581 * smp_call_function(). 581 * smp_call_function().
582 */ 582 */
583 lock_ipi_call_lock(); 583 lock_ipi_call_lock();
584 spin_lock(&vector_lock);
584 585
586 /* Setup the per cpu irq handling data structures */
587 __setup_vector_irq(smp_processor_id());
585 /* 588 /*
586 * Allow the master to continue. 589 * Allow the master to continue.
587 */ 590 */
588 cpu_set(smp_processor_id(), cpu_online_map); 591 cpu_set(smp_processor_id(), cpu_online_map);
589 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; 592 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
593 spin_unlock(&vector_lock);
590 unlock_ipi_call_lock(); 594 unlock_ipi_call_lock();
591 595
592 cpu_idle(); 596 cpu_idle();
@@ -799,7 +803,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
799 cpu, node); 803 cpu, node);
800 } 804 }
801 805
802
803 alternatives_smp_switch(1); 806 alternatives_smp_switch(1);
804 807
805 c_idle.idle = get_idle_for_cpu(cpu); 808 c_idle.idle = get_idle_for_cpu(cpu);
@@ -1246,8 +1249,10 @@ int __cpu_disable(void)
1246 local_irq_disable(); 1249 local_irq_disable();
1247 remove_siblinginfo(cpu); 1250 remove_siblinginfo(cpu);
1248 1251
1252 spin_lock(&vector_lock);
1249 /* It's now safe to remove this processor from the online map */ 1253 /* It's now safe to remove this processor from the online map */
1250 cpu_clear(cpu, cpu_online_map); 1254 cpu_clear(cpu, cpu_online_map);
1255 spin_unlock(&vector_lock);
1251 remove_cpu_from_maps(); 1256 remove_cpu_from_maps();
1252 fixup_irqs(cpu_online_map); 1257 fixup_irqs(cpu_online_map);
1253 return 0; 1258 return 0;