* [PATCH RFC] PM: sleep: Return -ECANCELED if aborting due to pm_wakeup_pending()
@ 2026-06-09 12:48 Nícolas F. R. A. Prado
2026-07-21 20:25 ` Nícolas F. R. A. Prado
0 siblings, 1 reply; 2+ messages in thread
From: Nícolas F. R. A. Prado @ 2026-06-09 12:48 UTC (permalink / raw)
To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
Danilo Krummrich, Thomas Gleixner, Peter Zijlstra
Cc: kernel, linux-pm, driver-core, linux-kernel, Nícolas F. R. A. Prado
If system sleep (suspend or hibernate) has been aborted due to
pm_wakeup_pending() returning true, return -ECANCELED so userspace can
tell it apart from actual failures.
ECANCELED is chosen both because it is a less common error code, so
it is less likely to be used for purposes other than the sleep abort due
to pending wakeups in this code path, and also because it more clearly
represents that the sleep was intentionally canceled.
Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
---
To give more context on my specific use case:
I want to address the situation where the system is running systemd's
suspend-then-hibernate and while going into hibernation, the user
triggers a wakeup (by pressing the power button). The expectation is
that the system would abort suspend-then-hibernate and wakeup, but
instead it considers that as a hibernation failure and falls back to
suspend instead. The key thing here is that systemd isn't able to tell
that this hibernation failure is not really a failure but an intentional
abort, which is where the consistent error code for pm_wakeup_pending()
can solve the problem.
Sending as an RFC as this is changing an ABI and although I'm not aware
of userspace that relies on the current error codes, it would be good to
get more input on this.
---
drivers/base/power/main.c | 4 ++--
drivers/base/syscore.c | 2 +-
kernel/cpu.c | 2 +-
kernel/power/hibernate.c | 9 +++++++--
kernel/power/process.c | 2 +-
kernel/power/suspend.c | 2 +-
6 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index ed48c292f575..8585fb94811c 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1646,7 +1646,7 @@ static void device_suspend_late(struct device *dev, pm_message_t state, bool asy
goto Complete;
if (pm_wakeup_pending()) {
- WRITE_ONCE(async_error, -EBUSY);
+ WRITE_ONCE(async_error, -ECANCELED);
goto Complete;
}
@@ -1902,7 +1902,7 @@ static void device_suspend(struct device *dev, pm_message_t state, bool async)
if (pm_wakeup_pending()) {
dev->power.direct_complete = false;
- WRITE_ONCE(async_error, -EBUSY);
+ WRITE_ONCE(async_error, -ECANCELED);
goto Complete;
}
diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c
index 483adb796654..37877b0cabd4 100644
--- a/drivers/base/syscore.c
+++ b/drivers/base/syscore.c
@@ -54,7 +54,7 @@ int syscore_suspend(void)
/* Return error code if there are any wakeup interrupts pending. */
if (pm_wakeup_pending())
- return -EBUSY;
+ return -ECANCELED;
WARN_ONCE(!irqs_disabled(),
"Interrupts enabled before system core suspend.\n");
diff --git a/kernel/cpu.c b/kernel/cpu.c
index f975bb34915b..7e46d51d2431 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1910,7 +1910,7 @@ int freeze_secondary_cpus(int primary)
if (pm_wakeup_pending()) {
pr_info("Wakeup pending. Abort CPU freeze\n");
- error = -EBUSY;
+ error = -ECANCELED;
break;
}
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index d2479c69d71a..56b431bf9b1d 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -349,9 +349,14 @@ static int create_image(int platform_mode)
goto Enable_irqs;
}
- if (hibernation_test(TEST_CORE) || pm_wakeup_pending())
+ if (hibernation_test(TEST_CORE))
goto Power_up;
+ if (pm_wakeup_pending()) {
+ error = -ECANCELED;
+ goto Power_up;
+ }
+
in_suspend = 1;
save_processor_state();
trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, true);
@@ -632,7 +637,7 @@ int hibernation_platform_enter(void)
goto Enable_irqs;
if (pm_wakeup_pending()) {
- error = -EAGAIN;
+ error = -ECANCELED;
goto Power_up;
}
diff --git a/kernel/power/process.c b/kernel/power/process.c
index dc0dfc349f22..bd164ccdcc2a 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -108,7 +108,7 @@ static int try_to_freeze_tasks(bool user_only)
what, elapsed_msecs / 1000, elapsed_msecs % 1000);
}
- return todo ? -EBUSY : 0;
+ return wakeup ? -ECANCELED : todo ? -EBUSY : 0;
}
/**
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 57c44268698f..8e1b43deb9e6 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -469,7 +469,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
trace_suspend_resume(TPS("machine_suspend"),
state, false);
} else if (*wakeup) {
- error = -EBUSY;
+ error = -ECANCELED;
}
syscore_resume();
}
---
base-commit: a87737435cfa134f9cdcc696ba3080759d04cf72
change-id: 20260609-wakeup-pending-ecanceled-e19bc14e6041
Best regards,
--
Nícolas F. R. A. Prado <nfraprado@collabora.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH RFC] PM: sleep: Return -ECANCELED if aborting due to pm_wakeup_pending()
2026-06-09 12:48 [PATCH RFC] PM: sleep: Return -ECANCELED if aborting due to pm_wakeup_pending() Nícolas F. R. A. Prado
@ 2026-07-21 20:25 ` Nícolas F. R. A. Prado
0 siblings, 0 replies; 2+ messages in thread
From: Nícolas F. R. A. Prado @ 2026-07-21 20:25 UTC (permalink / raw)
To: Rafael J. Wysocki, Len Brown, Pavel Machek, Greg Kroah-Hartman,
Danilo Krummrich, Thomas Gleixner, Peter Zijlstra
Cc: kernel, linux-pm, driver-core, linux-kernel
On Tue, 2026-06-09 at 08:48 -0400, Nícolas F. R. A. Prado wrote:
> If system sleep (suspend or hibernate) has been aborted due to
> pm_wakeup_pending() returning true, return -ECANCELED so userspace
> can
> tell it apart from actual failures.
>
> ECANCELED is chosen both because it is a less common error code, so
> it is less likely to be used for purposes other than the sleep abort
> due
> to pending wakeups in this code path, and also because it more
> clearly
> represents that the sleep was intentionally canceled.
>
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> ---
> To give more context on my specific use case:
>
> I want to address the situation where the system is running systemd's
> suspend-then-hibernate and while going into hibernation, the user
> triggers a wakeup (by pressing the power button). The expectation is
> that the system would abort suspend-then-hibernate and wakeup, but
> instead it considers that as a hibernation failure and falls back to
> suspend instead. The key thing here is that systemd isn't able to
> tell
> that this hibernation failure is not really a failure but an
> intentional
> abort, which is where the consistent error code for
> pm_wakeup_pending()
> can solve the problem.
>
> Sending as an RFC as this is changing an ABI and although I'm not
> aware
> of userspace that relies on the current error codes, it would be good
> to
> get more input on this.
Hi,
Any feedback on this RFC?
--
Thanks,
Nícolas
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-21 20:26 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-09 12:48 [PATCH RFC] PM: sleep: Return -ECANCELED if aborting due to pm_wakeup_pending() Nícolas F. R. A. Prado
2026-07-21 20:25 ` Nícolas F. R. A. Prado
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®