From 70a0a5357db20c291d46c04011d646d5d84c868c Mon Sep 17 00:00:00 2001 From: Eric W. Biederman Date: Wed, 25 Oct 2006 01:00:23 +0200 Subject: [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 Signed-off-by: Andi Kleen --- arch/x86_64/kernel/smpboot.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/x86_64/kernel/smpboot.c') 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) * smp_call_function(). */ lock_ipi_call_lock(); + spin_lock(&vector_lock); + /* Setup the per cpu irq handling data structures */ + __setup_vector_irq(smp_processor_id()); /* * Allow the master to continue. */ cpu_set(smp_processor_id(), cpu_online_map); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; + spin_unlock(&vector_lock); unlock_ipi_call_lock(); cpu_idle(); @@ -799,7 +803,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) cpu, node); } - alternatives_smp_switch(1); c_idle.idle = get_idle_for_cpu(cpu); @@ -1246,8 +1249,10 @@ int __cpu_disable(void) local_irq_disable(); remove_siblinginfo(cpu); + spin_lock(&vector_lock); /* It's now safe to remove this processor from the online map */ cpu_clear(cpu, cpu_online_map); + spin_unlock(&vector_lock); remove_cpu_from_maps(); fixup_irqs(cpu_online_map); return 0; -- cgit v1.2.3-55-g7522