<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/drivers/thermal, branch v4.2.4</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>thermal: cpu_cooling: free power table on error or when unregistering</title>
<updated>2015-10-22T21:49:27+00:00</updated>
<author>
<name>Javi Merino</name>
<email>javi.merino@arm.com</email>
</author>
<published>2015-08-17T18:21:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=fd4480eec8745c2e6b2d7764df520217f1633912'/>
<id>fd4480eec8745c2e6b2d7764df520217f1633912</id>
<content type='text'>
commit eba4f88d5af84e0fcaa5d6eb4fe35a75c47203cb upstream.

The power table is not being freed on error from cpufreq_cooling
register or when unregistering.  Free it.

Fixes: c36cf0717631 ("thermal: cpu_cooling: implement the power cooling device API")
Cc: Zhang Rui &lt;rui.zhang@intel.com&gt;
Cc: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Javi Merino &lt;javi.merino@arm.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit eba4f88d5af84e0fcaa5d6eb4fe35a75c47203cb upstream.

The power table is not being freed on error from cpufreq_cooling
register or when unregistering.  Free it.

Fixes: c36cf0717631 ("thermal: cpu_cooling: implement the power cooling device API")
Cc: Zhang Rui &lt;rui.zhang@intel.com&gt;
Cc: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Javi Merino &lt;javi.merino@arm.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: cpu_cooling: don't call kcalloc() under rcu_read_lock</title>
<updated>2015-10-22T21:49:27+00:00</updated>
<author>
<name>Javi Merino</name>
<email>javi.merino@arm.com</email>
</author>
<published>2015-08-17T18:21:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=333126b347ace518c17ebef5ef18a1a7e6721858'/>
<id>333126b347ace518c17ebef5ef18a1a7e6721858</id>
<content type='text'>
commit 459ac37506d195713b5e82271a2ac44a777e47df upstream.

build_dyn_power_table() allocates the power table while holding
rcu_read_lock.  kcalloc using GFP_KERNEL may sleep, so it can't be
called in an RCU read-side path.

Move the rcu protection to the part of the function that really needs
it: the part that handles the dev_pm_opp pointer received from
dev_pm_opp_find_freq_ceil().  In the unlikely case that there is an OPP
added to the cpu while this function is running, return -EAGAIN.

Fixes: c36cf0717631 ("thermal: cpu_cooling: implement the power cooling device API")
Cc: Zhang Rui &lt;rui.zhang@intel.com&gt;
Cc: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Javi Merino &lt;javi.merino@arm.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 459ac37506d195713b5e82271a2ac44a777e47df upstream.

build_dyn_power_table() allocates the power table while holding
rcu_read_lock.  kcalloc using GFP_KERNEL may sleep, so it can't be
called in an RCU read-side path.

Move the rcu protection to the part of the function that really needs
it: the part that handles the dev_pm_opp pointer received from
dev_pm_opp_find_freq_ceil().  In the unlikely case that there is an OPP
added to the cpu while this function is running, return -EAGAIN.

Fixes: c36cf0717631 ("thermal: cpu_cooling: implement the power cooling device API")
Cc: Zhang Rui &lt;rui.zhang@intel.com&gt;
Cc: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Javi Merino &lt;javi.merino@arm.com&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: power_allocator: allocate with kcalloc what you free with kfree</title>
<updated>2015-08-29T17:10:47+00:00</updated>
<author>
<name>Javi Merino</name>
<email>javi.merino@arm.com</email>
</author>
<published>2015-08-25T18:22:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=9751a9e449da2a7749d89968039d532c615beeaa'/>
<id>9751a9e449da2a7749d89968039d532c615beeaa</id>
<content type='text'>
Commit cf736ea6f902 ("thermal: power_allocator: do not use devm*
interfaces") forgot to change a devm_kcalloc() to just kcalloc(), but
it's corresponding devm_kfree() was changed to kfree().  Allocate with
kcalloc() to match the kfree().

Fixes: cf736ea6f902 ("thermal: power_allocator: do not use devm* interfaces")
Cc: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
Cc: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Cc: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Javi Merino &lt;javi.merino@arm.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Commit cf736ea6f902 ("thermal: power_allocator: do not use devm*
interfaces") forgot to change a devm_kcalloc() to just kcalloc(), but
it's corresponding devm_kfree() was changed to kfree().  Allocate with
kcalloc() to match the kfree().

Fixes: cf736ea6f902 ("thermal: power_allocator: do not use devm* interfaces")
Cc: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
Cc: Eduardo Valentin &lt;edubezval@gmail.com&gt;
Cc: Zhang Rui &lt;rui.zhang@intel.com&gt;
Signed-off-by: Javi Merino &lt;javi.merino@arm.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal/cpu_cooling: update policy limits if clipped_freq &lt; policy-&gt;max</title>
<updated>2015-08-15T01:26:23+00:00</updated>
<author>
<name>Viresh Kumar</name>
<email>viresh.kumar@linaro.org</email>
</author>
<published>2015-07-30T07:10:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=1afb9c539daebc2c8a7b33d0e0b8fc9f74671b02'/>
<id>1afb9c539daebc2c8a7b33d0e0b8fc9f74671b02</id>
<content type='text'>
policy-&gt;max is the maximum allowed frequency defined by user and
clipped_freq is the maximum that thermal constraints allow.

If clipped_freq is lower than policy-&gt;max, then we need to readjust
policy-&gt;max.

But, if clipped_freq is greater than policy-&gt;max, we don't need to do
anything. We used to call cpufreq_verify_within_limits() in this case,
but it doesn't change anything in this case.

Lets skip this unnecessary call and write a comment that explains this.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
policy-&gt;max is the maximum allowed frequency defined by user and
clipped_freq is the maximum that thermal constraints allow.

If clipped_freq is lower than policy-&gt;max, then we need to readjust
policy-&gt;max.

But, if clipped_freq is greater than policy-&gt;max, we don't need to do
anything. We used to call cpufreq_verify_within_limits() in this case,
but it doesn't change anything in this case.

Lets skip this unnecessary call and write a comment that explains this.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal/cpu_cooling: rename max_freq as clipped_freq in notifier</title>
<updated>2015-08-15T01:26:23+00:00</updated>
<author>
<name>Viresh Kumar</name>
<email>viresh.kumar@linaro.org</email>
</author>
<published>2015-07-30T07:10:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=abcbcc25cb3edfc3c9af210a88c9386e353191fe'/>
<id>abcbcc25cb3edfc3c9af210a88c9386e353191fe</id>
<content type='text'>
That's what it is for, lets name it properly.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
That's what it is for, lets name it properly.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal/cpu_cooling: rename cpufreq_val as clipped_freq</title>
<updated>2015-08-15T01:26:22+00:00</updated>
<author>
<name>Viresh Kumar</name>
<email>viresh.kumar@linaro.org</email>
</author>
<published>2015-07-30T07:10:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=59f0d21883f39d27f14408d4ca211dce80658963'/>
<id>59f0d21883f39d27f14408d4ca211dce80658963</id>
<content type='text'>
That's what it is for, lets name it properly.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
That's what it is for, lets name it properly.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal/cpu_cooling: convert 'switch' block to 'if' block in notifier</title>
<updated>2015-08-15T01:26:22+00:00</updated>
<author>
<name>Viresh Kumar</name>
<email>viresh.kumar@linaro.org</email>
</author>
<published>2015-07-30T07:10:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=a24af233a1fd09002cabc05d6da248cc5656a2e1'/>
<id>a24af233a1fd09002cabc05d6da248cc5656a2e1</id>
<content type='text'>
We just need to take care of single event here and there is no need to
increase indentation level of most of the code (which causes lines
longer that 80 columns to break).

Kill the switch block.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We just need to take care of single event here and there is no need to
increase indentation level of most of the code (which causes lines
longer that 80 columns to break).

Kill the switch block.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal/cpu_cooling: quit early after updating policy</title>
<updated>2015-08-15T01:26:22+00:00</updated>
<author>
<name>Viresh Kumar</name>
<email>viresh.kumar@linaro.org</email>
</author>
<published>2015-07-30T07:10:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=166529c9b6f91b97d771e2e7ebf748aadb239b44'/>
<id>166529c9b6f91b97d771e2e7ebf748aadb239b44</id>
<content type='text'>
If a valid cpufreq_dev is found for policy-&gt;cpu, we should update the
policy and quit the for loop. There is no need to keep traversing the
list of cpufreq_dev's.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If a valid cpufreq_dev is found for policy-&gt;cpu, we should update the
policy and quit the for loop. There is no need to keep traversing the
list of cpufreq_dev's.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal/cpu_cooling: No need to initialize max_freq to 0</title>
<updated>2015-08-15T01:26:22+00:00</updated>
<author>
<name>Viresh Kumar</name>
<email>viresh.kumar@linaro.org</email>
</author>
<published>2015-07-30T07:10:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=76fd38ce21de506a3867768fac42729eb6d7dedf'/>
<id>76fd38ce21de506a3867768fac42729eb6d7dedf</id>
<content type='text'>
Its always set before getting used, don't initialize it.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Its always set before getting used, don't initialize it.

Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>thermal: cpu_cooling: fix lockdep problems in cpu_cooling</title>
<updated>2015-08-15T01:21:41+00:00</updated>
<author>
<name>Russell King</name>
<email>rmk+kernel@arm.linux.org.uk</email>
</author>
<published>2015-08-12T09:52:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=02373d7c69b4270bbab930f8a81b0721be794347'/>
<id>02373d7c69b4270bbab930f8a81b0721be794347</id>
<content type='text'>
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:

======================================================
[ INFO: possible circular locking dependency detected ]
3.18.0+ #1453 Not tainted
-------------------------------------------------------
rc.local/770 is trying to acquire lock:
 (cooling_cpufreq_lock){+.+.+.}, at: [&lt;c04abfc4&gt;] cpufreq_thermal_notifier+0x34/0xfc

but task is already holding lock:
 ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [&lt;c0042f04&gt;]  __blocking_notifier_call_chain+0x34/0x68

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-&gt; #1 ((cpufreq_policy_notifier_list).rwsem){++++.+}:
       [&lt;c06bc3b0&gt;] down_write+0x44/0x9c
       [&lt;c0043444&gt;] blocking_notifier_chain_register+0x28/0xd8
       [&lt;c04ad610&gt;] cpufreq_register_notifier+0x68/0x90
       [&lt;c04abe4c&gt;] __cpufreq_cooling_register.part.1+0x120/0x180
       [&lt;c04abf44&gt;] __cpufreq_cooling_register+0x98/0xa4
       [&lt;c04abf8c&gt;] cpufreq_cooling_register+0x18/0x1c
       [&lt;bf0046f8&gt;] imx_thermal_probe+0x1c0/0x470 [imx_thermal]
       [&lt;c037cef8&gt;] platform_drv_probe+0x50/0xac
       [&lt;c037b710&gt;] driver_probe_device+0x114/0x234
       [&lt;c037b8cc&gt;] __driver_attach+0x9c/0xa0
       [&lt;c0379d68&gt;] bus_for_each_dev+0x5c/0x90
       [&lt;c037b204&gt;] driver_attach+0x24/0x28
       [&lt;c037ae7c&gt;] bus_add_driver+0xe0/0x1d8
       [&lt;c037c0cc&gt;] driver_register+0x80/0xfc
       [&lt;c037cd80&gt;] __platform_driver_register+0x50/0x64
       [&lt;bf007018&gt;] 0xbf007018
       [&lt;c0008a5c&gt;] do_one_initcall+0x88/0x1d8
       [&lt;c0095da4&gt;] load_module+0x1768/0x1ef8
       [&lt;c0096614&gt;] SyS_init_module+0xe0/0xf4
       [&lt;c000ec00&gt;] ret_fast_syscall+0x0/0x48

-&gt; #0 (cooling_cpufreq_lock){+.+.+.}:
       [&lt;c00619f8&gt;] lock_acquire+0xb0/0x124
       [&lt;c06ba3b4&gt;] mutex_lock_nested+0x5c/0x3d8
       [&lt;c04abfc4&gt;] cpufreq_thermal_notifier+0x34/0xfc
       [&lt;c0042bf4&gt;] notifier_call_chain+0x4c/0x8c
       [&lt;c0042f20&gt;] __blocking_notifier_call_chain+0x50/0x68
       [&lt;c0042f58&gt;] blocking_notifier_call_chain+0x20/0x28
       [&lt;c04ae62c&gt;] cpufreq_set_policy+0x7c/0x1d0
       [&lt;c04af3cc&gt;] store_scaling_governor+0x74/0x9c
       [&lt;c04ad418&gt;] store+0x90/0xc0
       [&lt;c0175384&gt;] sysfs_kf_write+0x54/0x58
       [&lt;c01746b4&gt;] kernfs_fop_write+0xdc/0x190
       [&lt;c010dcc0&gt;] vfs_write+0xac/0x1b4
       [&lt;c010dfec&gt;] SyS_write+0x44/0x90
       [&lt;c000ec00&gt;] ret_fast_syscall+0x0/0x48

other info that might help us debug this:

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock((cpufreq_policy_notifier_list).rwsem);
                               lock(cooling_cpufreq_lock);
                               lock((cpufreq_policy_notifier_list).rwsem);
  lock(cooling_cpufreq_lock);

 *** DEADLOCK ***

7 locks held by rc.local/770:
 #0:  (sb_writers#6){.+.+.+}, at: [&lt;c010dda0&gt;] vfs_write+0x18c/0x1b4
 #1:  (&amp;of-&gt;mutex){+.+.+.}, at: [&lt;c0174678&gt;] kernfs_fop_write+0xa0/0x190
 #2:  (s_active#52){.+.+.+}, at: [&lt;c0174680&gt;] kernfs_fop_write+0xa8/0x190
 #3:  (cpu_hotplug.lock){++++++}, at: [&lt;c0026a60&gt;] get_online_cpus+0x34/0x90
 #4:  (cpufreq_rwsem){.+.+.+}, at: [&lt;c04ad3e0&gt;] store+0x58/0xc0
 #5:  (&amp;policy-&gt;rwsem){+.+.+.}, at: [&lt;c04ad3f8&gt;] store+0x70/0xc0
 #6:  ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [&lt;c0042f04&gt;] __blocking_notifier_call_chain+0x34/0x68

stack backtrace:
CPU: 0 PID: 770 Comm: rc.local Not tainted 3.18.0+ #1453
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace:
[&lt;c00121c8&gt;] (dump_backtrace) from [&lt;c0012360&gt;] (show_stack+0x18/0x1c)
 r6:c0b85a80 r5:c0b75630 r4:00000000 r3:00000000
[&lt;c0012348&gt;] (show_stack) from [&lt;c06b6c48&gt;] (dump_stack+0x7c/0x98)
[&lt;c06b6bcc&gt;] (dump_stack) from [&lt;c06b42a4&gt;] (print_circular_bug+0x28c/0x2d8)
 r4:c0b85a80 r3:d0071d40
[&lt;c06b4018&gt;] (print_circular_bug) from [&lt;c00613b0&gt;] (__lock_acquire+0x1acc/0x1bb0)
 r10:c0b50660 r8:c09e6d80 r7:d0071d40 r6:c11d0f0c r5:00000007 r4:d0072240
[&lt;c005f8e4&gt;] (__lock_acquire) from [&lt;c00619f8&gt;] (lock_acquire+0xb0/0x124)
 r10:00000000 r9:c04abfc4 r8:00000000 r7:00000000 r6:00000000 r5:c0a06f0c
 r4:00000000
[&lt;c0061948&gt;] (lock_acquire) from [&lt;c06ba3b4&gt;] (mutex_lock_nested+0x5c/0x3d8)
 r10:ec853800 r9:c0a06ed4 r8:d0071d40 r7:c0a06ed4 r6:c11d0f0c r5:00000000
 r4:c04abfc4
[&lt;c06ba358&gt;] (mutex_lock_nested) from [&lt;c04abfc4&gt;] (cpufreq_thermal_notifier+0x34/0xfc)
 r10:ec853800 r9:ec85380c r8:d00d7d3c r7:c0a06ed4 r6:d00d7d3c r5:00000000
 r4:fffffffe
[&lt;c04abf90&gt;] (cpufreq_thermal_notifier) from [&lt;c0042bf4&gt;] (notifier_call_chain+0x4c/0x8c)
 r7:00000000 r6:00000000 r5:00000000 r4:fffffffe
[&lt;c0042ba8&gt;] (notifier_call_chain) from [&lt;c0042f20&gt;] (__blocking_notifier_call_chain+0x50/0x68)
 r8:c0a072a4 r7:00000000 r6:d00d7d3c r5:ffffffff r4:c0a06fc8 r3:ffffffff
[&lt;c0042ed0&gt;] (__blocking_notifier_call_chain) from [&lt;c0042f58&gt;] (blocking_notifier_call_chain+0x20/0x28)
 r7:ec98b540 r6:c13ebc80 r5:ed76e600 r4:d00d7d3c
[&lt;c0042f38&gt;] (blocking_notifier_call_chain) from [&lt;c04ae62c&gt;] (cpufreq_set_policy+0x7c/0x1d0)
[&lt;c04ae5b0&gt;] (cpufreq_set_policy) from [&lt;c04af3cc&gt;] (store_scaling_governor+0x74/0x9c)
 r7:ec98b540 r6:0000000c r5:ec98b540 r4:ed76e600
[&lt;c04af358&gt;] (store_scaling_governor) from [&lt;c04ad418&gt;] (store+0x90/0xc0)
 r6:0000000c r5:ed76e6d4 r4:ed76e600
[&lt;c04ad388&gt;] (store) from [&lt;c0175384&gt;] (sysfs_kf_write+0x54/0x58)
 r8:0000000c r7:d00d7f78 r6:ec98b540 r5:0000000c r4:ec853800 r3:0000000c
[&lt;c0175330&gt;] (sysfs_kf_write) from [&lt;c01746b4&gt;] (kernfs_fop_write+0xdc/0x190)
 r6:ec98b540 r5:00000000 r4:00000000 r3:c0175330
[&lt;c01745d8&gt;] (kernfs_fop_write) from [&lt;c010dcc0&gt;] (vfs_write+0xac/0x1b4)
 r10:0162aa70 r9:d00d6000 r8:0000000c r7:d00d7f78 r6:0162aa70 r5:0000000c
 r4:eccde500
[&lt;c010dc14&gt;] (vfs_write) from [&lt;c010dfec&gt;] (SyS_write+0x44/0x90)
 r10:0162aa70 r8:0000000c r7:eccde500 r6:eccde500 r5:00000000 r4:00000000
[&lt;c010dfa8&gt;] (SyS_write) from [&lt;c000ec00&gt;] (ret_fast_syscall+0x0/0x48)
 r10:00000000 r8:c000edc4 r7:00000004 r6:000216cc r5:0000000c r4:0162aa70

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.

cooling_list_lock is taken within cooling_cpufreq_lock on
(un)registration to preserve the behavior of the code, i.e. to
atomically add/remove to the list and (un)register the notifier.

Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq policy with
Reviewed-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Russell King &lt;rmk+kernel@arm.linux.org.uk&gt;
Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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:

======================================================
[ INFO: possible circular locking dependency detected ]
3.18.0+ #1453 Not tainted
-------------------------------------------------------
rc.local/770 is trying to acquire lock:
 (cooling_cpufreq_lock){+.+.+.}, at: [&lt;c04abfc4&gt;] cpufreq_thermal_notifier+0x34/0xfc

but task is already holding lock:
 ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [&lt;c0042f04&gt;]  __blocking_notifier_call_chain+0x34/0x68

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-&gt; #1 ((cpufreq_policy_notifier_list).rwsem){++++.+}:
       [&lt;c06bc3b0&gt;] down_write+0x44/0x9c
       [&lt;c0043444&gt;] blocking_notifier_chain_register+0x28/0xd8
       [&lt;c04ad610&gt;] cpufreq_register_notifier+0x68/0x90
       [&lt;c04abe4c&gt;] __cpufreq_cooling_register.part.1+0x120/0x180
       [&lt;c04abf44&gt;] __cpufreq_cooling_register+0x98/0xa4
       [&lt;c04abf8c&gt;] cpufreq_cooling_register+0x18/0x1c
       [&lt;bf0046f8&gt;] imx_thermal_probe+0x1c0/0x470 [imx_thermal]
       [&lt;c037cef8&gt;] platform_drv_probe+0x50/0xac
       [&lt;c037b710&gt;] driver_probe_device+0x114/0x234
       [&lt;c037b8cc&gt;] __driver_attach+0x9c/0xa0
       [&lt;c0379d68&gt;] bus_for_each_dev+0x5c/0x90
       [&lt;c037b204&gt;] driver_attach+0x24/0x28
       [&lt;c037ae7c&gt;] bus_add_driver+0xe0/0x1d8
       [&lt;c037c0cc&gt;] driver_register+0x80/0xfc
       [&lt;c037cd80&gt;] __platform_driver_register+0x50/0x64
       [&lt;bf007018&gt;] 0xbf007018
       [&lt;c0008a5c&gt;] do_one_initcall+0x88/0x1d8
       [&lt;c0095da4&gt;] load_module+0x1768/0x1ef8
       [&lt;c0096614&gt;] SyS_init_module+0xe0/0xf4
       [&lt;c000ec00&gt;] ret_fast_syscall+0x0/0x48

-&gt; #0 (cooling_cpufreq_lock){+.+.+.}:
       [&lt;c00619f8&gt;] lock_acquire+0xb0/0x124
       [&lt;c06ba3b4&gt;] mutex_lock_nested+0x5c/0x3d8
       [&lt;c04abfc4&gt;] cpufreq_thermal_notifier+0x34/0xfc
       [&lt;c0042bf4&gt;] notifier_call_chain+0x4c/0x8c
       [&lt;c0042f20&gt;] __blocking_notifier_call_chain+0x50/0x68
       [&lt;c0042f58&gt;] blocking_notifier_call_chain+0x20/0x28
       [&lt;c04ae62c&gt;] cpufreq_set_policy+0x7c/0x1d0
       [&lt;c04af3cc&gt;] store_scaling_governor+0x74/0x9c
       [&lt;c04ad418&gt;] store+0x90/0xc0
       [&lt;c0175384&gt;] sysfs_kf_write+0x54/0x58
       [&lt;c01746b4&gt;] kernfs_fop_write+0xdc/0x190
       [&lt;c010dcc0&gt;] vfs_write+0xac/0x1b4
       [&lt;c010dfec&gt;] SyS_write+0x44/0x90
       [&lt;c000ec00&gt;] ret_fast_syscall+0x0/0x48

other info that might help us debug this:

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock((cpufreq_policy_notifier_list).rwsem);
                               lock(cooling_cpufreq_lock);
                               lock((cpufreq_policy_notifier_list).rwsem);
  lock(cooling_cpufreq_lock);

 *** DEADLOCK ***

7 locks held by rc.local/770:
 #0:  (sb_writers#6){.+.+.+}, at: [&lt;c010dda0&gt;] vfs_write+0x18c/0x1b4
 #1:  (&amp;of-&gt;mutex){+.+.+.}, at: [&lt;c0174678&gt;] kernfs_fop_write+0xa0/0x190
 #2:  (s_active#52){.+.+.+}, at: [&lt;c0174680&gt;] kernfs_fop_write+0xa8/0x190
 #3:  (cpu_hotplug.lock){++++++}, at: [&lt;c0026a60&gt;] get_online_cpus+0x34/0x90
 #4:  (cpufreq_rwsem){.+.+.+}, at: [&lt;c04ad3e0&gt;] store+0x58/0xc0
 #5:  (&amp;policy-&gt;rwsem){+.+.+.}, at: [&lt;c04ad3f8&gt;] store+0x70/0xc0
 #6:  ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [&lt;c0042f04&gt;] __blocking_notifier_call_chain+0x34/0x68

stack backtrace:
CPU: 0 PID: 770 Comm: rc.local Not tainted 3.18.0+ #1453
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace:
[&lt;c00121c8&gt;] (dump_backtrace) from [&lt;c0012360&gt;] (show_stack+0x18/0x1c)
 r6:c0b85a80 r5:c0b75630 r4:00000000 r3:00000000
[&lt;c0012348&gt;] (show_stack) from [&lt;c06b6c48&gt;] (dump_stack+0x7c/0x98)
[&lt;c06b6bcc&gt;] (dump_stack) from [&lt;c06b42a4&gt;] (print_circular_bug+0x28c/0x2d8)
 r4:c0b85a80 r3:d0071d40
[&lt;c06b4018&gt;] (print_circular_bug) from [&lt;c00613b0&gt;] (__lock_acquire+0x1acc/0x1bb0)
 r10:c0b50660 r8:c09e6d80 r7:d0071d40 r6:c11d0f0c r5:00000007 r4:d0072240
[&lt;c005f8e4&gt;] (__lock_acquire) from [&lt;c00619f8&gt;] (lock_acquire+0xb0/0x124)
 r10:00000000 r9:c04abfc4 r8:00000000 r7:00000000 r6:00000000 r5:c0a06f0c
 r4:00000000
[&lt;c0061948&gt;] (lock_acquire) from [&lt;c06ba3b4&gt;] (mutex_lock_nested+0x5c/0x3d8)
 r10:ec853800 r9:c0a06ed4 r8:d0071d40 r7:c0a06ed4 r6:c11d0f0c r5:00000000
 r4:c04abfc4
[&lt;c06ba358&gt;] (mutex_lock_nested) from [&lt;c04abfc4&gt;] (cpufreq_thermal_notifier+0x34/0xfc)
 r10:ec853800 r9:ec85380c r8:d00d7d3c r7:c0a06ed4 r6:d00d7d3c r5:00000000
 r4:fffffffe
[&lt;c04abf90&gt;] (cpufreq_thermal_notifier) from [&lt;c0042bf4&gt;] (notifier_call_chain+0x4c/0x8c)
 r7:00000000 r6:00000000 r5:00000000 r4:fffffffe
[&lt;c0042ba8&gt;] (notifier_call_chain) from [&lt;c0042f20&gt;] (__blocking_notifier_call_chain+0x50/0x68)
 r8:c0a072a4 r7:00000000 r6:d00d7d3c r5:ffffffff r4:c0a06fc8 r3:ffffffff
[&lt;c0042ed0&gt;] (__blocking_notifier_call_chain) from [&lt;c0042f58&gt;] (blocking_notifier_call_chain+0x20/0x28)
 r7:ec98b540 r6:c13ebc80 r5:ed76e600 r4:d00d7d3c
[&lt;c0042f38&gt;] (blocking_notifier_call_chain) from [&lt;c04ae62c&gt;] (cpufreq_set_policy+0x7c/0x1d0)
[&lt;c04ae5b0&gt;] (cpufreq_set_policy) from [&lt;c04af3cc&gt;] (store_scaling_governor+0x74/0x9c)
 r7:ec98b540 r6:0000000c r5:ec98b540 r4:ed76e600
[&lt;c04af358&gt;] (store_scaling_governor) from [&lt;c04ad418&gt;] (store+0x90/0xc0)
 r6:0000000c r5:ed76e6d4 r4:ed76e600
[&lt;c04ad388&gt;] (store) from [&lt;c0175384&gt;] (sysfs_kf_write+0x54/0x58)
 r8:0000000c r7:d00d7f78 r6:ec98b540 r5:0000000c r4:ec853800 r3:0000000c
[&lt;c0175330&gt;] (sysfs_kf_write) from [&lt;c01746b4&gt;] (kernfs_fop_write+0xdc/0x190)
 r6:ec98b540 r5:00000000 r4:00000000 r3:c0175330
[&lt;c01745d8&gt;] (kernfs_fop_write) from [&lt;c010dcc0&gt;] (vfs_write+0xac/0x1b4)
 r10:0162aa70 r9:d00d6000 r8:0000000c r7:d00d7f78 r6:0162aa70 r5:0000000c
 r4:eccde500
[&lt;c010dc14&gt;] (vfs_write) from [&lt;c010dfec&gt;] (SyS_write+0x44/0x90)
 r10:0162aa70 r8:0000000c r7:eccde500 r6:eccde500 r5:00000000 r4:00000000
[&lt;c010dfa8&gt;] (SyS_write) from [&lt;c000ec00&gt;] (ret_fast_syscall+0x0/0x48)
 r10:00000000 r8:c000edc4 r7:00000004 r6:000216cc r5:0000000c r4:0162aa70

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.

cooling_list_lock is taken within cooling_cpufreq_lock on
(un)registration to preserve the behavior of the code, i.e. to
atomically add/remove to the list and (un)register the notifier.

Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq policy with
Reviewed-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Russell King &lt;rmk+kernel@arm.linux.org.uk&gt;
Signed-off-by: Viresh Kumar &lt;viresh.kumar@linaro.org&gt;
Signed-off-by: Eduardo Valentin &lt;edubezval@gmail.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
