Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ee349ad authored by Xiaotian Feng's avatar Xiaotian Feng Committed by Ingo Molnar
Browse files

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: default avatarSachin Sant <sachinp@in.ibm.com>
Signed-off-by: default avatarXiaotian Feng <dfeng@redhat.com>
Tested-by: default avatarSachin Sant <sachinp@in.ibm.com>
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
LKML-Reference: <20091216170517.500272612@chello.nl>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 933b0618
Loading
Loading
Loading
Loading
+3 −21
Original line number Diff line number Diff line
@@ -209,6 +209,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
		return -ENOMEM;

	cpu_hotplug_begin();
	set_cpu_active(cpu, false);
	err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
					hcpu, -1, &nr_calls);
	if (err == NOTIFY_BAD) {
@@ -280,18 +281,6 @@ int __ref cpu_down(unsigned int cpu)
		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);

out:
@@ -382,19 +371,12 @@ int disable_nonboot_cpus(void)
		return error;
	cpu_maps_update_begin();
	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
	 */
	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");
	for_each_online_cpu(cpu) {
		if (cpu == first_cpu)