Re: [RFC PATCH v1] PM: wakeup: Provide interface for userspace to abort suspend
From: Rafael J. Wysocki
Date: Mon Jul 21 2025 - 15:51:25 EST
On Fri, Jul 18, 2025 at 9:18 AM Saravana Kannan <saravanak@xxxxxxxxxx> wrote:
>
> Once suspend starts, it can take a while before file system sync
> finishes and all the userspace threads are frozen. During this time,
> there can be events that originate in userspace that would require the
> suspend to be aborted.
>
> The only way to abort suspend from userspace as of today is to grab
> and release a kernel wakelock using the /sys/power/wake_lock and
> /sys/power/wake_unlock files. This has the disadvantage of:
>
> * Doing the useless work of creating and destroying wakelocks.
> * If the userspace entity crashes after the wake lock is created, we
> get a wake lock/memory leak.
But wakelocks are for this purpose.
> To avoid all this and simplify the interface, this patch allows
> canceling a suspend by writing UINT_MAX value to the
> /sys/power/wakeup_count that is meant for tracking wakeup events.
>
> Signed-off-by: Saravana Kannan <saravanak@xxxxxxxxxx>
> ---
>
> Rafael,
>
> If the idea looks good to you, I can also update Documentation and sent
> it as a non-RFC patch. I'm not too tied on what file we use to trigger
> an abort from userspace as long as it's possible.
I would rather add an interface based on a special device file for
wakelocks to address this.
For example, open it to create a wakelock with the name of a calling
process, write 1 to it to block suspending, write 0 to it to unblock,
close to remove it.
Then it will go away automatically when the process exits.
> drivers/base/power/wakeup.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
> index d1283ff1080b..9316de561bcc 100644
> --- a/drivers/base/power/wakeup.c
> +++ b/drivers/base/power/wakeup.c
> @@ -1008,6 +1008,8 @@ bool pm_save_wakeup_count(unsigned int count)
> if (cnt == count && inpr == 0) {
> saved_count = count;
> events_check_enabled = true;
> + } else if (cnt == UINT_MAX) {
> + pm_system_wakeup();
> }
> raw_spin_unlock_irqrestore(&events_lock, flags);
> return events_check_enabled;
> --
> 2.50.0.727.gbf7dc18ff4-goog
>
>