[3.13.y.z extended stable] Patch "ACPI / cpuidle: fix deadlock between cpuidle_lock and cpu_hotplug.lock" has been added to staging queue

Kamal Mostafa kamal at canonical.com
Tue Sep 30 21:29:49 UTC 2014


This is a note to let you know that I have just added a patch titled

    ACPI / cpuidle: fix deadlock between cpuidle_lock and cpu_hotplug.lock

to the linux-3.13.y-queue branch of the 3.13.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.13.y-queue

This patch is scheduled to be released in version 3.13.11.8.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.13.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

>From 8a87a486e0c7a44c5e100104ff025fbcf244a15d Mon Sep 17 00:00:00 2001
From: Jiri Kosina <jkosina at suse.cz>
Date: Wed, 3 Sep 2014 15:04:28 +0200
Subject: ACPI / cpuidle: fix deadlock between cpuidle_lock and
 cpu_hotplug.lock

commit 6726655dfdd2dc60c035c690d9f10cb69d7ea075 upstream.

There is a following AB-BA dependency between cpu_hotplug.lock and
cpuidle_lock:

1) cpu_hotplug.lock -> cpuidle_lock
enable_nonboot_cpus()
 _cpu_up()
  cpu_hotplug_begin()
   LOCK(cpu_hotplug.lock)
 cpu_notify()
  ...
  acpi_processor_hotplug()
   cpuidle_pause_and_lock()
    LOCK(cpuidle_lock)

2) cpuidle_lock -> cpu_hotplug.lock
acpi_os_execute_deferred() workqueue
 ...
 acpi_processor_cst_has_changed()
  cpuidle_pause_and_lock()
   LOCK(cpuidle_lock)
  get_online_cpus()
   LOCK(cpu_hotplug.lock)

Fix this by reversing the order acpi_processor_cst_has_changed() does
thigs -- let it first execute the protection against CPU hotplug by
calling get_online_cpus() and obtain the cpuidle lock only after that (and
perform the symmentric change when allowing CPUs hotplug again and
dropping cpuidle lock).

Spotted by lockdep.

Signed-off-by: Jiri Kosina <jkosina at suse.cz>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
 drivers/acpi/processor_idle.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 644516d..ba60290 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -1089,9 +1089,9 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)

 	if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) {

-		cpuidle_pause_and_lock();
 		/* Protect against cpu-hotplug */
 		get_online_cpus();
+		cpuidle_pause_and_lock();

 		/* Disable all cpuidle devices */
 		for_each_online_cpu(cpu) {
@@ -1118,8 +1118,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
 				cpuidle_enable_device(dev);
 			}
 		}
-		put_online_cpus();
 		cpuidle_resume_and_unlock();
+		put_online_cpus();
 	}

 	return 0;
--
1.9.1





More information about the kernel-team mailing list