|
40 | 40 |
|
41 | 41 | typedef int (*pm_callback_t)(struct device *);
|
42 | 42 |
|
| 43 | +#define list_for_each_entry_rcu_locked(pos, head, member) \ |
| 44 | + list_for_each_entry_rcu(pos, head, member, \ |
| 45 | + device_links_read_lock_held()) |
| 46 | + |
43 | 47 | /*
|
44 | 48 | * The entries in the dpm_list list are in a depth first order, simply
|
45 | 49 | * because children are guaranteed to be discovered after parents, and
|
@@ -266,7 +270,7 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async)
|
266 | 270 | * callbacks freeing the link objects for the links in the list we're
|
267 | 271 | * walking.
|
268 | 272 | */
|
269 |
| - list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) |
| 273 | + list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) |
270 | 274 | if (READ_ONCE(link->status) != DL_STATE_DORMANT)
|
271 | 275 | dpm_wait(link->supplier, async);
|
272 | 276 |
|
@@ -323,7 +327,7 @@ static void dpm_wait_for_consumers(struct device *dev, bool async)
|
323 | 327 | * continue instead of trying to continue in parallel with its
|
324 | 328 | * unregistration).
|
325 | 329 | */
|
326 |
| - list_for_each_entry_rcu(link, &dev->links.consumers, s_node) |
| 330 | + list_for_each_entry_rcu_locked(link, &dev->links.consumers, s_node) |
327 | 331 | if (READ_ONCE(link->status) != DL_STATE_DORMANT)
|
328 | 332 | dpm_wait(link->consumer, async);
|
329 | 333 |
|
@@ -1235,7 +1239,7 @@ static void dpm_superior_set_must_resume(struct device *dev)
|
1235 | 1239 |
|
1236 | 1240 | idx = device_links_read_lock();
|
1237 | 1241 |
|
1238 |
| - list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) |
| 1242 | + list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) |
1239 | 1243 | link->supplier->power.must_resume = true;
|
1240 | 1244 |
|
1241 | 1245 | device_links_read_unlock(idx);
|
@@ -1695,7 +1699,7 @@ static void dpm_clear_superiors_direct_complete(struct device *dev)
|
1695 | 1699 |
|
1696 | 1700 | idx = device_links_read_lock();
|
1697 | 1701 |
|
1698 |
| - list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) { |
| 1702 | + list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) { |
1699 | 1703 | spin_lock_irq(&link->supplier->power.lock);
|
1700 | 1704 | link->supplier->power.direct_complete = false;
|
1701 | 1705 | spin_unlock_irq(&link->supplier->power.lock);
|
|
0 commit comments