Commit b4718c02f49ab5e1452353f0fae78beabe81467c
Committed by
Rafael J. Wysocki
1 parent
0fe30da2cb
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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>
Showing 1 changed file with 8 additions and 7 deletions Side-by-side Diff
drivers/base/power/opp.c
| ... | ... | @@ -216,9 +216,7 @@ |
| 216 | 216 | * This function returns the number of available opps if there are any, |
| 217 | 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 | |
| 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. | |
| 219 | + * Locking: This function takes rcu_read_lock(). | |
| 222 | 220 | */ |
| 223 | 221 | int dev_pm_opp_get_opp_count(struct device *dev) |
| 224 | 222 | { |
| 225 | 223 | |
| ... | ... | @@ -226,13 +224,14 @@ |
| 226 | 224 | struct dev_pm_opp *temp_opp; |
| 227 | 225 | int count = 0; |
| 228 | 226 | |
| 229 | - opp_rcu_lockdep_assert(); | |
| 227 | + rcu_read_lock(); | |
| 230 | 228 | |
| 231 | 229 | dev_opp = find_device_opp(dev); |
| 232 | 230 | if (IS_ERR(dev_opp)) { |
| 233 | - int r = PTR_ERR(dev_opp); | |
| 234 | - dev_err(dev, "%s: device OPP not found (%d)\n", __func__, r); | |
| 235 | - return r; | |
| 231 | + count = PTR_ERR(dev_opp); | |
| 232 | + dev_err(dev, "%s: device OPP not found (%d)\n", | |
| 233 | + __func__, count); | |
| 234 | + goto out_unlock; | |
| 236 | 235 | } |
| 237 | 236 | |
| 238 | 237 | list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { |
| ... | ... | @@ -240,6 +239,8 @@ |
| 240 | 239 | count++; |
| 241 | 240 | } |
| 242 | 241 | |
| 242 | +out_unlock: | |
| 243 | + rcu_read_unlock(); | |
| 243 | 244 | return count; |
| 244 | 245 | } |
| 245 | 246 | EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); |