3.18: lockdep problems in cpufreq
From: viresh.kumar@linaro.org (Viresh Kumar)
Date: 2014-12-15 03:56:59
Also in:
linux-pm
On 15 December 2014 at 03:53, Rafael J. Wysocki [off-list ref] wrote:
On Sunday, December 14, 2014 09:36:55 PM Russell King - ARM Linux wrote:quoted
Here's a nice Christmas present one of my iMX6 machines gave me tonight. I haven't begun to look into it.
Is the culprit this one?
Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq
policy with thermal constraints")
As this is what it changed:
@@ -316,21 +312,28 @@ static int cpufreq_thermal_notifier(structnotifier_block *nb,
{
struct cpufreq_policy *policy = data;
unsigned long max_freq = 0;
+ struct cpufreq_cooling_device *cpufreq_dev;
- if (event != CPUFREQ_ADJUST || notify_device == NOTIFY_INVALID)
+ if (event != CPUFREQ_ADJUST)
return 0;
- if (cpumask_test_cpu(policy->cpu, ¬ify_device->allowed_cpus))
- max_freq = notify_device->cpufreq_val;
- else
- return 0;
+ mutex_lock(&cooling_cpufreq_lock);
+ list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
+ if (!cpumask_test_cpu(policy->cpu,
+ &cpufreq_dev->allowed_cpus))
+ continue;
+
+ if (!cpufreq_dev->cpufreq_val)
+ cpufreq_dev->cpufreq_val = get_cpu_frequency(
+ cpumask_any(&cpufreq_dev->allowed_cpus),
+ cpufreq_dev->cpufreq_state);
- /* Never exceed user_policy.max */
- if (max_freq > policy->user_policy.max)
- max_freq = policy->user_policy.max;
+ max_freq = cpufreq_dev->cpufreq_val;
- if (policy->max != max_freq)
- cpufreq_verify_within_limits(policy, 0, max_freq);
+ if (policy->max != max_freq)
+ cpufreq_verify_within_limits(policy, 0, max_freq);
+ }
+ mutex_unlock(&cooling_cpufreq_lock);
return 0;
}
quoted
====================================================== [ INFO: possible circular locking dependency detected ] 3.18.0+ #1453 Not tainted ------------------------------------------------------- rc.local/770 is trying to acquire lock: (cooling_cpufreq_lock){+.+.+.}, at: [<c04abfc4>] cpufreq_thermal_notifier+0x34/0xfc but task is already holding lock: ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [<c0042f04>] __blocking_notifier_call_chain+0x34/0x68 which lock already depends on the new lock.Well, that's for Viresh.
Maybe not as the rework I have done is queued for this merge window. I was afraid really after reading the "offenders" discussion on IRC :) Cc'd Yadwinder as well who wrote this patch.