Re: [PATCH 1/2] PM: hibernate: add pm_hibernation_storing_image() helper
From: Rafael J. Wysocki
Date: Tue May 26 2026 - 09:48:55 EST
On Tue, Apr 28, 2026 at 10:06 AM Haowen Tu <tuhaowen@xxxxxxxxxxxxx> wrote:
>
> During hibernation, after create_image() saves the memory snapshot,
> the kernel resumes devices with PMSG_THAW solely to write the hibernation
> image to storage, then powers off. Drivers for hardware not involved in
> storage I/O have no reason to reinitialize during this transient phase.
>
> Some subsystems, such as USB, do not expose the hibernation PM message
> to driver resume callbacks, so drivers there need an explicit query to
> distinguish the image-write phase from the final restore path. Export
> pm_hibernation_storing_image() for this purpose.
>
> The implementation returns !!in_suspend, which is set to 1 in
> create_image() just before swsusp_arch_suspend() and reset to 0 in
> hibernate() after swsusp_write() completes. Because in_suspend is
> marked __nosavedata, it is not saved into the hibernation image; on the
> restore path the variable remains 0 throughout, so the helper correctly
> returns false during PMSG_RESTORE device resume.
>
> Signed-off-by: Haowen Tu <tuhaowen@xxxxxxxxxxxxx>
> ---
> include/linux/suspend.h | 2 ++
> kernel/power/hibernate.c | 19 +++++++++++++++++++
> 2 files changed, 21 insertions(+)
>
> diff --git a/include/linux/suspend.h b/include/linux/suspend.h
> index b02876f1ae38..28b454def83d 100644
> --- a/include/linux/suspend.h
> +++ b/include/linux/suspend.h
> @@ -393,6 +393,7 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops);
> extern int hibernate(void);
> extern bool system_entering_hibernation(void);
> extern bool hibernation_available(void);
> +extern bool pm_hibernation_storing_image(void);
> asmlinkage int swsusp_save(void);
> extern struct pbe *restore_pblist;
> int pfn_is_nosave(unsigned long pfn);
> @@ -412,6 +413,7 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op
> static inline int hibernate(void) { return -ENOSYS; }
> static inline bool system_entering_hibernation(void) { return false; }
> static inline bool hibernation_available(void) { return false; }
> +static inline bool pm_hibernation_storing_image(void) { return false; }
>
> static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) {
> return -ENOTSUPP;
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index af8d07bafe02..bc632cce40ff 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -113,6 +113,25 @@ bool hibernation_available(void)
> !secretmem_active() && !cxl_mem_active();
> }
>
> +/**
> + * pm_hibernation_storing_image - check if system is writing the hibernation image
> + *
> + * After create_image() saves a memory snapshot, the kernel briefly resumes
> + * devices with PMSG_THAW to write the image to storage before final powerdown.
> + * Drivers for hardware not involved in storage I/O may call this helper from
> + * their resume callbacks to skip unnecessary hardware initialization during
> + * that transient phase.
> + *
> + * Context: May be called from device PM callbacks.
> + * Return: %true if a hibernation snapshot has been taken and the system is
> + * in the process of writing the image to persistent storage.
> + */
> +bool pm_hibernation_storing_image(void)
> +{
> + return !!in_suspend;
> +}
> +EXPORT_SYMBOL_GPL(pm_hibernation_storing_image);
Could this be called pm_hibernation_snapshot_done(), please?
Also, since it relies on in_suspend, please double check that
in_suspend is cleared properly in all hibernation failure/test paths
(basically, it must be cleared if the snapshot memory is going to be
released).