* [PATCH v1] PM: sleep: core: Clear power.must_resume in noirq suspend error path
@ 2025-09-02 13:55 Rafael J. Wysocki
2025-09-04 9:26 ` Ulf Hansson
0 siblings, 1 reply; 2+ messages in thread
From: Rafael J. Wysocki @ 2025-09-02 13:55 UTC (permalink / raw)
To: Linux PM; +Cc: LKML, Ulf Hansson
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
If system suspend is aborted in the "noirq" phase (for instance, due to
an error returned by one of the device callbacks), power.is_noirq_suspended
will not be set for some devices and device_resume_noirq() will return
early for them. Consequently, noirq resume callbacks will not run for
them at all because the noirq suspend callbacks have not run for them
yet.
If any of them has power.must_resume set and late suspend has been
skipped for it (due to power.smart_suspend), early resume should be
skipped for it either, or its state may become inconsistent (for
instance, if the early resume assumes that it will always follow
noirq resume).
Make that happen by clearing power.must_resume in device_resume_noirq()
for devices with power.is_noirq_suspended clear that have been left in
suspend by device_suspend_late(), which will subsequently cause
device_resume_early() to leave the device in suspend and avoid
changing its state.
Fixes: 0d4b54c6fee8 ("PM / core: Add LEAVE_SUSPENDED driver flag")
Link: https://lore.kernel.org/linux-pm/5d692b81-6f58-4e86-9cb0-ede69a09d799@rowland.harvard.edu/
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/base/power/main.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -720,8 +720,20 @@
if (dev->power.syscore || dev->power.direct_complete)
goto Out;
- if (!dev->power.is_noirq_suspended)
+ if (!dev->power.is_noirq_suspended) {
+ /*
+ * This means that system suspend has been aborted in the noirq
+ * phase before invoking the noirq suspend callback for the
+ * device, so if device_suspend_late() has left it in suspend,
+ * device_resume_early() should leave it in suspend either in
+ * case the early resume of it depends on the noirq resume that
+ * has not run.
+ */
+ if (dev_pm_skip_suspend(dev))
+ dev->power.must_resume = false;
+
goto Out;
+ }
if (!dpm_wait_for_superior(dev, async))
goto Out;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v1] PM: sleep: core: Clear power.must_resume in noirq suspend error path
2025-09-02 13:55 [PATCH v1] PM: sleep: core: Clear power.must_resume in noirq suspend error path Rafael J. Wysocki
@ 2025-09-04 9:26 ` Ulf Hansson
0 siblings, 0 replies; 2+ messages in thread
From: Ulf Hansson @ 2025-09-04 9:26 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Linux PM, LKML
On Tue, 2 Sept 2025 at 15:55, Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> If system suspend is aborted in the "noirq" phase (for instance, due to
> an error returned by one of the device callbacks), power.is_noirq_suspended
> will not be set for some devices and device_resume_noirq() will return
> early for them. Consequently, noirq resume callbacks will not run for
> them at all because the noirq suspend callbacks have not run for them
> yet.
>
> If any of them has power.must_resume set and late suspend has been
> skipped for it (due to power.smart_suspend), early resume should be
> skipped for it either, or its state may become inconsistent (for
> instance, if the early resume assumes that it will always follow
> noirq resume).
>
> Make that happen by clearing power.must_resume in device_resume_noirq()
> for devices with power.is_noirq_suspended clear that have been left in
> suspend by device_suspend_late(), which will subsequently cause
> device_resume_early() to leave the device in suspend and avoid
> changing its state.
>
> Fixes: 0d4b54c6fee8 ("PM / core: Add LEAVE_SUSPENDED driver flag")
> Link: https://lore.kernel.org/linux-pm/5d692b81-6f58-4e86-9cb0-ede69a09d799@rowland.harvard.edu/
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Kind regards
Uffe
> ---
> drivers/base/power/main.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
>
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -720,8 +720,20 @@
> if (dev->power.syscore || dev->power.direct_complete)
> goto Out;
>
> - if (!dev->power.is_noirq_suspended)
> + if (!dev->power.is_noirq_suspended) {
> + /*
> + * This means that system suspend has been aborted in the noirq
> + * phase before invoking the noirq suspend callback for the
> + * device, so if device_suspend_late() has left it in suspend,
> + * device_resume_early() should leave it in suspend either in
> + * case the early resume of it depends on the noirq resume that
> + * has not run.
> + */
> + if (dev_pm_skip_suspend(dev))
> + dev->power.must_resume = false;
> +
> goto Out;
> + }
>
> if (!dpm_wait_for_superior(dev, async))
> goto Out;
>
>
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-09-04 9:27 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-02 13:55 [PATCH v1] PM: sleep: core: Clear power.must_resume in noirq suspend error path Rafael J. Wysocki
2025-09-04 9:26 ` Ulf Hansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox