From: viresh.kumar@linaro.org (Viresh Kumar)
To: linux-arm-kernel@lists.infradead.org
Subject: 3.18: lockdep problems in cpufreq
Date: Wed, 12 Aug 2015 13:42:57 +0530 [thread overview]
Message-ID: <20150812081257.GC16445@linux> (raw)
In-Reply-To: <20150812074925.GG7557@n2100.arm.linux.org.uk>
On 12-08-15, 08:49, Russell King - ARM Linux wrote:
> The problem will be back-porting it to stable kernels, because I think
> it's had to be updated at least a couple of times. I don't have the old
> versions anymore, so I'm just going to say "not my problem" - sorry.
Your old 3.18 version :)
8<===
From: Russell King <rmk+kernel@arm.linux.org.uk>
thermal: cpu_cooling: fix lockdep problems in cpu_cooling
A recent change to the cpu_cooling code introduced a AB-BA deadlock
scenario between the cpufreq_policy_notifier_list rwsem and the
cooling_cpufreq_lock. This is caused by cooling_cpufreq_lock being held
before the registration/removal of the notifier block (an operation
which takes the rwsem), and the notifier code itself which takes the
locks in the reverse order.
Solve this by moving to finer grained locking - use one mutex to protect
the cpufreq_dev_list as a whole, and a separate lock to ensure correct
ordering of cpufreq notifier registration and removal.
I considered taking the cooling_list_lock within cooling_cpufreq_lock to
protect the registration sequence as a whole, but that adds a dependency
between these two locks which is best avoided (lest someone tries to
take those two new locks in the reverse order.) In any case, it's safer
to have an empty cpufreq_dev_list than to have unnecessary dependencies
between locks.
Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq policy with thermal constraints")
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/thermal/cpu_cooling.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index ad09e51ffae4..9e42c6f30785 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -57,6 +57,7 @@ static DEFINE_MUTEX(cooling_cpufreq_lock);
static unsigned int cpufreq_dev_count;
+static DEFINE_MUTEX(cooling_list_lock);
static LIST_HEAD(cpufreq_dev_list);
/**
@@ -317,7 +318,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
if (event != CPUFREQ_ADJUST)
return 0;
- mutex_lock(&cooling_cpufreq_lock);
+ mutex_lock(&cooling_list_lock);
list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
if (!cpumask_test_cpu(policy->cpu,
&cpufreq_dev->allowed_cpus))
@@ -333,7 +334,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
if (policy->max != max_freq)
cpufreq_verify_within_limits(policy, 0, max_freq);
}
- mutex_unlock(&cooling_cpufreq_lock);
+ mutex_unlock(&cooling_list_lock);
return 0;
}
@@ -482,6 +483,11 @@ __cpufreq_cooling_register(struct device_node *np,
}
cpufreq_dev->cool_dev = cool_dev;
cpufreq_dev->cpufreq_state = 0;
+
+ mutex_lock(&cooling_list_lock);
+ list_add(&cpufreq_dev->node, &cpufreq_dev_list);
+ mutex_unlock(&cooling_list_lock);
+
mutex_lock(&cooling_cpufreq_lock);
/* Register the notifier for first cpufreq cooling device */
@@ -489,7 +495,6 @@ __cpufreq_cooling_register(struct device_node *np,
cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
CPUFREQ_POLICY_NOTIFIER);
cpufreq_dev_count++;
- list_add(&cpufreq_dev->node, &cpufreq_dev_list);
mutex_unlock(&cooling_cpufreq_lock);
@@ -553,7 +558,6 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
cpufreq_dev = cdev->devdata;
mutex_lock(&cooling_cpufreq_lock);
- list_del(&cpufreq_dev->node);
cpufreq_dev_count--;
/* Unregister the notifier for the last cpufreq cooling device */
@@ -562,6 +566,10 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
CPUFREQ_POLICY_NOTIFIER);
mutex_unlock(&cooling_cpufreq_lock);
+ mutex_lock(&cooling_list_lock);
+ list_del(&cpufreq_dev->node);
+ mutex_unlock(&cooling_list_lock);
+
thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
release_idr(&cpufreq_idr, cpufreq_dev->id);
kfree(cpufreq_dev);
next prev parent reply other threads:[~2015-08-12 8:12 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-14 21:36 3.18: lockdep problems in cpufreq Russell King - ARM Linux
2014-12-14 22:23 ` Rafael J. Wysocki
2014-12-15 3:56 ` Viresh Kumar
2014-12-15 13:28 ` Yadwinder Singh Brar
2014-12-15 13:46 ` Russell King - ARM Linux
2014-12-15 14:54 ` Yadwinder Singh Brar
2014-12-15 17:43 ` Russell King - ARM Linux
2014-12-15 21:41 ` Rafael J. Wysocki
2014-12-15 23:09 ` Russell King - ARM Linux
2014-12-16 3:41 ` Viresh Kumar
2015-01-06 15:38 ` Russell King - ARM Linux
2015-05-18 18:56 ` Russell King - ARM Linux
2015-05-18 22:05 ` Rafael J. Wysocki
2015-08-11 17:03 ` Russell King - ARM Linux
2015-08-12 5:16 ` Viresh Kumar
2015-08-12 7:21 ` Russell King - ARM Linux
2015-08-12 7:35 ` Viresh Kumar
2015-08-12 7:41 ` [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling Russell King
2015-08-12 8:11 ` Viresh Kumar
2015-08-12 9:08 ` Russell King - ARM Linux
2015-08-12 9:18 ` Viresh Kumar
2015-08-14 4:50 ` Eduardo Valentin
2015-08-14 5:53 ` Viresh Kumar
2015-08-15 1:19 ` Eduardo Valentin
2015-08-15 3:06 ` Viresh Kumar
2015-08-12 7:49 ` 3.18: lockdep problems in cpufreq Russell King - ARM Linux
2015-08-12 8:12 ` Viresh Kumar [this message]
2015-08-12 9:08 ` Russell King - ARM Linux
2015-08-12 9:19 ` Viresh Kumar
2015-08-13 1:20 ` Rafael J. Wysocki
2015-08-13 8:17 ` Russell King - ARM Linux
2015-08-13 8:22 ` Viresh Kumar
2015-08-18 1:32 ` Rafael J. Wysocki
2015-08-18 9:30 ` Eduardo Valentin
2014-12-16 3:37 ` Viresh Kumar
2014-12-15 14:38 ` Viresh Kumar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150812081257.GC16445@linux \
--to=viresh.kumar@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).