summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2011-12-15 17:09:22 +0100
committerNitin Garg <nitin.garg@freescale.com>2014-06-03 21:52:36 -0500
commitcc89d7ad1f80b0293c2cb2e8527898c399f814a6 (patch)
treed8f0a55ae0a34dc46822fa056b8e52afb1585590
parent41fd42bfcf35ee1160ae449c56e53393b7f72438 (diff)
sched: Cleanup cpu_active madness
Stepan found: CPU0 CPUn _cpu_up() __cpu_up() boostrap() notify_cpu_starting() set_cpu_online() while (!cpu_active()) cpu_relax() <PREEMPT-out> smp_call_function(.wait=1) /* we find cpu_online() is true */ arch_send_call_function_ipi_mask() /* wait-forever-more */ <PREEMPT-in> local_irq_enable() cpu_notify(CPU_ONLINE) sched_cpu_active() set_cpu_active() Now the purpose of cpu_active is mostly with bringing down a cpu, where we mark it !active to avoid the load-balancer from moving tasks to it while we tear down the cpu. This is required because we only update the sched_domain tree after we brought the cpu-down. And this is needed so that some tasks can still run while we bring it down, we just don't want new tasks to appear. On cpu-up however the sched_domain tree doesn't yet include the new cpu, so its invisible to the load-balancer, regardless of the active state. So instead of setting the active state after we boot the new cpu (and consequently having to wait for it before enabling interrupts) set the cpu active before we set it online and avoid the whole mess. Reported-by: Stepan Moskovchenko <stepanm@codeaurora.org> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1323965362.18942.71.camel@twins Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/arm/kernel/smp.c7
-rw-r--r--kernel/sched.c2
2 files changed, 1 insertions, 8 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index f3cd0d8e5108..cff496c9f3d1 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -325,13 +325,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
*/
percpu_timer_setup();
- while (!cpu_active(cpu))
- cpu_relax();
-
- /*
- * cpu_active bit is set, so it's safe to enable interrupts
- * now.
- */
local_irq_enable();
local_fiq_enable();
diff --git a/kernel/sched.c b/kernel/sched.c
index 0d037009000c..89459c5e759b 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6479,7 +6479,7 @@ static int __cpuinit sched_cpu_active(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
switch (action & ~CPU_TASKS_FROZEN) {
- case CPU_ONLINE:
+ case CPU_STARTING:
case CPU_DOWN_FAILED:
set_cpu_active((long)hcpu, true);
return NOTIFY_OK;