diff options
author | Dmitry Torokhov <dtor@chromium.org> | 2014-12-16 18:09:38 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-12-17 19:42:49 -0500 |
commit | b4718c02f49ab5e1452353f0fae78beabe81467c (patch) | |
tree | 7eb5b9f28f79d6cb0d43f5b6ea62d77eac6806a4 | |
parent | 0fe30da2cb43782ee62d30c00a273d6934e5370e (diff) |
PM / OPP: take RCU lock in dev_pm_opp_get_opp_count
A lot of callers are missing the fact that dev_pm_opp_get_opp_count
needs to be called under RCU lock. Given that RCU locks can safely be
nested, instead of providing *_locked() API, let's take RCU lock inside
dev_pm_opp_get_opp_count() and leave callers as is.
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/power/opp.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index aac7abcf74f8..106c69359306 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
@@ -216,9 +216,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); | |||
216 | * This function returns the number of available opps if there are any, | 216 | * This function returns the number of available opps if there are any, |
217 | * else returns 0 if none or the corresponding error value. | 217 | * else returns 0 if none or the corresponding error value. |
218 | * | 218 | * |
219 | * Locking: This function must be called under rcu_read_lock(). This function | 219 | * Locking: This function takes rcu_read_lock(). |
220 | * internally references two RCU protected structures: device_opp and opp which | ||
221 | * are safe as long as we are under a common RCU locked section. | ||
222 | */ | 220 | */ |
223 | int dev_pm_opp_get_opp_count(struct device *dev) | 221 | int dev_pm_opp_get_opp_count(struct device *dev) |
224 | { | 222 | { |
@@ -226,13 +224,14 @@ int dev_pm_opp_get_opp_count(struct device *dev) | |||
226 | struct dev_pm_opp *temp_opp; | 224 | struct dev_pm_opp *temp_opp; |
227 | int count = 0; | 225 | int count = 0; |
228 | 226 | ||
229 | opp_rcu_lockdep_assert(); | 227 | rcu_read_lock(); |
230 | 228 | ||
231 | dev_opp = find_device_opp(dev); | 229 | dev_opp = find_device_opp(dev); |
232 | if (IS_ERR(dev_opp)) { | 230 | if (IS_ERR(dev_opp)) { |
233 | int r = PTR_ERR(dev_opp); | 231 | count = PTR_ERR(dev_opp); |
234 | dev_err(dev, "%s: device OPP not found (%d)\n", __func__, r); | 232 | dev_err(dev, "%s: device OPP not found (%d)\n", |
235 | return r; | 233 | __func__, count); |
234 | goto out_unlock; | ||
236 | } | 235 | } |
237 | 236 | ||
238 | list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { | 237 | list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { |
@@ -240,6 +239,8 @@ int dev_pm_opp_get_opp_count(struct device *dev) | |||
240 | count++; | 239 | count++; |
241 | } | 240 | } |
242 | 241 | ||
242 | out_unlock: | ||
243 | rcu_read_unlock(); | ||
243 | return count; | 244 | return count; |
244 | } | 245 | } |
245 | EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); | 246 | EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); |