Message ID | 4553341.LvFx2qVVIh@kreacher (mailing list archive) |
---|---|
State | In Next |
Delegated to: | Rafael Wysocki |
Headers | show |
Series | PM: sleep: Fix up suspend stats handling and clean up core code | expand |
On Mon, Jan 22, 2024 at 12:22:38PM +0100, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > Notice that devices can be moved to dpm_prepared_list before running > their resume callbacks, in analogy with dpm_noirq_resume_devices() and > dpm_resume_early(), because doing so will not affect the final ordering > of that list. > > Namely, if a device is the first dpm_suspended_list entry while > dpm_list_mtx is held, it has not been removed so far and it cannot be > removed until dpm_list_mtx is released, so moving it to dpm_prepared_list > at that point is valid. If it is removed later, while its resume > callback is running, it will be deleted from dpm_prepared_list without > changing the ordering of the other devices in that list. > > Accordingly, rearrange the while () loop in dpm_resume() to move > devices to dpm_prepared_list before running their resume callbacks and > implify the locking and device reference counting in it. > > No intentional functional impact. > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> > --- > drivers/base/power/main.c | 16 +++++----------- > 1 file changed, 5 insertions(+), 11 deletions(-) > > Index: linux-pm/drivers/base/power/main.c > =================================================================== > --- linux-pm.orig/drivers/base/power/main.c > +++ linux-pm/drivers/base/power/main.c > @@ -1017,25 +1017,19 @@ void dpm_resume(pm_message_t state) > > while (!list_empty(&dpm_suspended_list)) { > dev = to_device(dpm_suspended_list.next); > - > - get_device(dev); > + list_move_tail(&dev->power.entry, &dpm_prepared_list); > > if (!dev->power.async_in_progress) { > + get_device(dev); > + > mutex_unlock(&dpm_list_mtx); > > device_resume(dev, state, false); > > + put_device(dev); > + > mutex_lock(&dpm_list_mtx); > } > - > - if (!list_empty(&dev->power.entry)) > - list_move_tail(&dev->power.entry, &dpm_prepared_list); > - > - mutex_unlock(&dpm_list_mtx); > - > - put_device(dev); > - > - mutex_lock(&dpm_list_mtx); > } > mutex_unlock(&dpm_list_mtx); > async_synchronize_full(); > > >
Index: linux-pm/drivers/base/power/main.c =================================================================== --- linux-pm.orig/drivers/base/power/main.c +++ linux-pm/drivers/base/power/main.c @@ -1017,25 +1017,19 @@ void dpm_resume(pm_message_t state) while (!list_empty(&dpm_suspended_list)) { dev = to_device(dpm_suspended_list.next); - - get_device(dev); + list_move_tail(&dev->power.entry, &dpm_prepared_list); if (!dev->power.async_in_progress) { + get_device(dev); + mutex_unlock(&dpm_list_mtx); device_resume(dev, state, false); + put_device(dev); + mutex_lock(&dpm_list_mtx); } - - if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &dpm_prepared_list); - - mutex_unlock(&dpm_list_mtx); - - put_device(dev); - - mutex_lock(&dpm_list_mtx); } mutex_unlock(&dpm_list_mtx); async_synchronize_full();