Skip to content

Commit 5fbd036

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
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 <[email protected]> Signed-off-by: Peter Zijlstra <[email protected]> Acked-by: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/1323965362.18942.71.camel@twins Signed-off-by: Ingo Molnar <[email protected]>
1 parent 5d6523e commit 5fbd036

File tree

5 files changed

+1
-29
lines changed

5 files changed

+1
-29
lines changed

arch/arm/kernel/smp.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
295295
*/
296296
percpu_timer_setup();
297297

298-
while (!cpu_active(cpu))
299-
cpu_relax();
300-
301-
/*
302-
* cpu_active bit is set, so it's safe to enalbe interrupts
303-
* now.
304-
*/
305298
local_irq_enable();
306299
local_fiq_enable();
307300

arch/hexagon/kernel/smp.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,6 @@ void __cpuinit start_secondary(void)
179179
printk(KERN_INFO "%s cpu %d\n", __func__, current_thread_info()->cpu);
180180

181181
set_cpu_online(cpu, true);
182-
while (!cpumask_test_cpu(cpu, cpu_active_mask))
183-
cpu_relax();
184182
local_irq_enable();
185183

186184
cpu_idle();

arch/s390/kernel/smp.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -550,12 +550,6 @@ int __cpuinit start_secondary(void *cpuvoid)
550550
S390_lowcore.restart_psw.addr =
551551
PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
552552
__ctl_set_bit(0, 28); /* Enable lowcore protection */
553-
/*
554-
* Wait until the cpu which brought this one up marked it
555-
* active before enabling interrupts.
556-
*/
557-
while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask))
558-
cpu_relax();
559553
local_irq_enable();
560554
/* cpu_idle will call schedule for us */
561555
cpu_idle();

arch/x86/kernel/smpboot.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -291,19 +291,6 @@ notrace static void __cpuinit start_secondary(void *unused)
291291
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
292292
x86_platform.nmi_init();
293293

294-
/*
295-
* Wait until the cpu which brought this one up marked it
296-
* online before enabling interrupts. If we don't do that then
297-
* we can end up waking up the softirq thread before this cpu
298-
* reached the active state, which makes the scheduler unhappy
299-
* and schedule the softirq thread on the wrong cpu. This is
300-
* only observable with forced threaded interrupts, but in
301-
* theory it could also happen w/o them. It's just way harder
302-
* to achieve.
303-
*/
304-
while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask))
305-
cpu_relax();
306-
307294
/* enable local interrupts */
308295
local_irq_enable();
309296

kernel/sched/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5410,7 +5410,7 @@ static int __cpuinit sched_cpu_active(struct notifier_block *nfb,
54105410
unsigned long action, void *hcpu)
54115411
{
54125412
switch (action & ~CPU_TASKS_FROZEN) {
5413-
case CPU_ONLINE:
5413+
case CPU_STARTING:
54145414
case CPU_DOWN_FAILED:
54155415
set_cpu_active((long)hcpu, true);
54165416
return NOTIFY_OK;

0 commit comments

Comments
 (0)