Commit 918c1fe9 authored by Zhenzhong Duan's avatar Zhenzhong Duan Committed by Rafael J. Wysocki
Browse files

cpuidle: Do not unset the driver if it is there already



Fix __cpuidle_set_driver() to check if any of the CPUs in the mask has
a driver different from drv already and, if so, return -EBUSY before
updating any cpuidle_drivers per-CPU pointers.

Fixes: 82467a5a ("cpuidle: simplify multiple driver support")
Cc: 3.11+ <stable@vger.kernel.org> # 3.11+
Signed-off-by: default avatarZhenzhong Duan <zhenzhong.duan@oracle.com>
[ rjw: Subject & changelog ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 2c2a83d3
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -62,24 +62,23 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
 * __cpuidle_set_driver - set per CPU driver variables for the given driver.
 * @drv: a valid pointer to a struct cpuidle_driver
 *
 * For each CPU in the driver's cpumask, unset the registered driver per CPU
 * to @drv.
 *
 * Returns 0 on success, -EBUSY if the CPUs have driver(s) already.
 * Returns 0 on success, -EBUSY if any CPU in the cpumask have a driver
 * different from drv already.
 */
static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
{
	int cpu;

	for_each_cpu(cpu, drv->cpumask) {
		struct cpuidle_driver *old_drv;

		if (__cpuidle_get_cpu_driver(cpu)) {
			__cpuidle_unset_driver(drv);
		old_drv = __cpuidle_get_cpu_driver(cpu);
		if (old_drv && old_drv != drv)
			return -EBUSY;
	}

	for_each_cpu(cpu, drv->cpumask)
		per_cpu(cpuidle_drivers, cpu) = drv;
	}

	return 0;
}