On Mon, Oct 13, 2025 at 7:48 PM Mario Limonciello (AMD) <[email protected]> wrote: > > From: Mario Limonciello <[email protected]> > > After the hibernation snapshot is created all devices will have > their thaw() callback called before the next stage. For the most > common scenarios of hibernation this is not necessary because the > device will be powered off anyway.
And how exactly is the image going to be saved? It is only in memory when the "thaw" callbacks are invoked. > If the hibernation snapshot was successfully created skip thawing > devices until it's needed for userspace created hibernation image > or hybrid sleep. To accomplish this use PMSG_INVALID in > hibernation_snapshot() and set the dpm functions to skip running. > > Signed-off-by: Mario Limonciello <[email protected]> > --- > drivers/base/power/main.c | 6 ++++++ > kernel/power/hibernate.c | 13 ++++++++++--- > kernel/power/user.c | 3 +++ > 3 files changed, 19 insertions(+), 3 deletions(-) > > diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c > index 8179fd53171dc..58f5270a173e8 100644 > --- a/drivers/base/power/main.c > +++ b/drivers/base/power/main.c > @@ -1143,6 +1143,9 @@ void dpm_resume(pm_message_t state) > struct device *dev; > ktime_t starttime = ktime_get(); > > + if (state.event == PM_EVENT_INVALID) > + return; > + > trace_suspend_resume(TPS("dpm_resume"), state.event, true); > > pm_transition = state; > @@ -1245,6 +1248,9 @@ void dpm_complete(pm_message_t state) > { > struct list_head list; > > + if (state.event == PM_EVENT_INVALID) > + return; > + > trace_suspend_resume(TPS("dpm_complete"), state.event, true); > > INIT_LIST_HEAD(&list); > diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c > index aadf82f57e868..7af2e392c574a 100644 > --- a/kernel/power/hibernate.c > +++ b/kernel/power/hibernate.c > @@ -480,13 +480,14 @@ int hibernation_snapshot(int platform_mode) > if (error || !in_suspend) > swsusp_free(); > > - msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; > + msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_INVALID) : > PMSG_RESTORE; > dpm_resume(msg); > > - if (error || !in_suspend) > + if (error || !in_suspend) { > pm_restore_gfp_mask(); > + console_resume_all(); > + } > > - console_resume_all(); > dpm_complete(msg); > > Close: > @@ -707,7 +708,13 @@ static void power_down(void) > > #ifdef CONFIG_SUSPEND > if (hibernation_mode == HIBERNATION_SUSPEND) { > + /* recover from hibernation_snapshot() */ > + dpm_resume(PMSG_THAW); > + console_resume_all(); > + dpm_complete(PMSG_THAW); > pm_restore_gfp_mask(); > + > + /* run suspend sequence */ > error = suspend_devices_and_enter(mem_sleep_current); > if (!error) > goto exit; > diff --git a/kernel/power/user.c b/kernel/power/user.c > index 3f9e3efb9f6e7..d70c963b1ba88 100644 > --- a/kernel/power/user.c > +++ b/kernel/power/user.c > @@ -310,6 +310,9 @@ static long snapshot_ioctl(struct file *filp, unsigned > int cmd, > pm_restore_gfp_mask(); > error = hibernation_snapshot(data->platform_support); > if (!error) { > + dpm_resume(PMSG_THAW); > + console_resume_all(); > + dpm_complete(PMSG_THAW); > error = put_user(in_suspend, (int __user *)arg); > data->ready = !freezer_test_done && !error; > freezer_test_done = false; > -- > 2.43.0 >
