PM / devfreq: governor_cpufreq: Rewrite locking to avoid deadlocks
A devfreq governor store in parallel with a cpu freq update can cause
deadlock as shown below.
Assume current devfreq governor is cpufreq, and user tries to change
to some other governor.
Write to sysfs store_governor | cpufreq driver updating cpu freq
------------------------------- | -----------------------------------
echo bw_hwmon > governor |
| takes rcu_read_lock and calls all
| cpufreq transition callbacks for
| PRECHANGE or POSTCHANGE
|
GOV_STOP on governor_cpufreq. |
unregister_cpufreq() accquires |
state_lock mutex. |
| try to accquire same state_lock in
| cpufreq_trans_notifier(). Blocked.
unregister from cpufreq |
transition notifier and wait for|
all rcu_readers to finish. |
Deadlock
A similar deadlock can happen with governor change and policy notifier
callbacks.
The state_lock currently protects multiple unrelated critical
sections: registering/unregistering of cpufreq notifiers, read/writing
the device list, and tracking the cpu states and updating device
frequencies. There is no need for register/unregister of the cpufreq
notifiers to be mutually excluded against the other critical sections
using the same lock.
Split state_lock into two locks to protect the register/unregister of
cpufreq notifiers from the rest of the critical sections.
Change-Id: Id06d326748a5cb0c84c4787da5d0910f44eb5c3c
Signed-off-by: Pan Fang <fangpan@codeaurora.org>
Signed-off-by: Arun KS <arunks@codeaurora.org>
Signed-off-by: Junjie Wu <junjiew@codeaurora.org>
Suggested-by: Saravana Kannan <skannan@codeaurora.org>
1 file changed