]> git.neil.brown.name Git - history.git/commitdiff
[CPUFREQ] Fix deadlock in userspace governor.
authorDave Jones <davej@redhat.com>
Tue, 10 Feb 2004 18:03:26 +0000 (18:03 +0000)
committerDave Jones <davej@delerium.codemonkey.org.uk>
Tue, 10 Feb 2004 18:03:26 +0000 (18:03 +0000)
Another fix from Dominik.

drivers/cpufreq/cpufreq_userspace.c

index f69c42445d2a140e55ff0dbc06db7beae808b3e6..709dddc0d369581c2283f38e87a71c2c0179b67f 100644 (file)
@@ -2,7 +2,7 @@
  *  linux/drivers/cpufreq/cpufreq_userspace.c
  *
  *  Copyright (C)  2001 Russell King
- *            (C)  2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *            (C)  2002 - 2004 Dominik Brodowski <linux@brodo.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -112,7 +112,14 @@ int cpufreq_set(unsigned int freq, unsigned int cpu)
        if (freq > cpu_max_freq[cpu])
                freq = cpu_max_freq[cpu];
 
-       ret = cpufreq_driver_target(&current_policy[cpu], freq, 
+       /*
+        * We're safe from concurrent calls to ->target() here
+        * as we hold the userspace_sem lock. If we were calling
+        * cpufreq_driver_target, a deadlock situation might occur:
+        * A: cpufreq_set (lock userspace_sem) -> cpufreq_driver_target(lock policy->lock)
+        * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_sem)
+        */
+       ret = __cpufreq_driver_target(&current_policy[cpu], freq, 
              CPUFREQ_RELATION_L);
 
  err: