mirror of
https://github.com/adulau/aha.git
synced 2024-12-26 18:56:14 +00:00
sched: Fix set_cpu_active() in cpu_down()
Sachin found cpu hotplug test failures on powerpc, which made the kernel hang on his POWER box. The problem is that we fail to re-activate a cpu when a hot-unplug fails. Fix this by moving the de-activation into _cpu_down after doing the initial checks. Remove the synchronize_sched() calls and rely on those implied by rebuilding the sched domains using the new mask. Reported-by: Sachin Sant <sachinp@in.ibm.com> Signed-off-by: Xiaotian Feng <dfeng@redhat.com> Tested-by: Sachin Sant <sachinp@in.ibm.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> LKML-Reference: <20091216170517.500272612@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
933b0618d8
commit
9ee349ad6d
1 changed files with 3 additions and 21 deletions
24
kernel/cpu.c
24
kernel/cpu.c
|
@ -209,6 +209,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
cpu_hotplug_begin();
|
cpu_hotplug_begin();
|
||||||
|
set_cpu_active(cpu, false);
|
||||||
err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
|
err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
|
||||||
hcpu, -1, &nr_calls);
|
hcpu, -1, &nr_calls);
|
||||||
if (err == NOTIFY_BAD) {
|
if (err == NOTIFY_BAD) {
|
||||||
|
@ -280,18 +281,6 @@ int __ref cpu_down(unsigned int cpu)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_cpu_active(cpu, false);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure the all cpus did the reschedule and are not
|
|
||||||
* using stale version of the cpu_active_mask.
|
|
||||||
* This is not strictly necessary becuase stop_machine()
|
|
||||||
* that we run down the line already provides the required
|
|
||||||
* synchronization. But it's really a side effect and we do not
|
|
||||||
* want to depend on the innards of the stop_machine here.
|
|
||||||
*/
|
|
||||||
synchronize_sched();
|
|
||||||
|
|
||||||
err = _cpu_down(cpu, 0);
|
err = _cpu_down(cpu, 0);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -382,19 +371,12 @@ int disable_nonboot_cpus(void)
|
||||||
return error;
|
return error;
|
||||||
cpu_maps_update_begin();
|
cpu_maps_update_begin();
|
||||||
first_cpu = cpumask_first(cpu_online_mask);
|
first_cpu = cpumask_first(cpu_online_mask);
|
||||||
/* We take down all of the non-boot CPUs in one shot to avoid races
|
/*
|
||||||
|
* We take down all of the non-boot CPUs in one shot to avoid races
|
||||||
* with the userspace trying to use the CPU hotplug at the same time
|
* with the userspace trying to use the CPU hotplug at the same time
|
||||||
*/
|
*/
|
||||||
cpumask_clear(frozen_cpus);
|
cpumask_clear(frozen_cpus);
|
||||||
|
|
||||||
for_each_online_cpu(cpu) {
|
|
||||||
if (cpu == first_cpu)
|
|
||||||
continue;
|
|
||||||
set_cpu_active(cpu, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronize_sched();
|
|
||||||
|
|
||||||
printk("Disabling non-boot CPUs ...\n");
|
printk("Disabling non-boot CPUs ...\n");
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
if (cpu == first_cpu)
|
if (cpu == first_cpu)
|
||||||
|
|
Loading…
Reference in a new issue