mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
To: "Rafael J. Wysocki" <rafael@kernel.org>,
	Len Brown <lenb@kernel.org>,  Pavel Machek <pavel@kernel.org>,
	 Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	 Danilo Krummrich <dakr@kernel.org>,
	Thomas Gleixner <tglx@kernel.org>,
	 Peter Zijlstra <peterz@infradead.org>
Cc: kernel@collabora.com, linux-pm@vger.kernel.org,
	driver-core@lists.linux.dev, linux-kernel@vger.kernel.org,
	"Nícolas F. R. A. Prado" <nfraprado@collabora.com>
Subject: [PATCH RFC] PM: sleep: Return -ECANCELED if aborting due to pm_wakeup_pending()
Date: Tue, 09 Jun 2026 08:48:39 -0400	[thread overview]
Message-ID: <20260609-wakeup-pending-ecanceled-v1-1-428d897c07cb@collabora.com> (raw)

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>


             reply	other threads:[~2026-06-09 12:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-09 12:48 Nícolas F. R. A. Prado [this message]
2026-07-21 20:25 ` Nícolas F. R. A. Prado

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260609-wakeup-pending-ecanceled-v1-1-428d897c07cb@collabora.com \
    --to=nfraprado@collabora.com \
    --cc=dakr@kernel.org \
    --cc=driver-core@lists.linux.dev \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel@collabora.com \
    --cc=lenb@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=pavel@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rafael@kernel.org \
    --cc=tglx@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®