[PATCH v4 1/4] PM: hibernate: clear in_suspend before freeing the snapshot
Haowen Tu <[email protected]>
| Newsgroups | org.kernel.vger.linux-pm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-media,org.kernel.vger.linux-usb |
|---|---|
| Message-ID | <4fafe6c2c7bc99e8b4e5042eae19ad9587f99cc1.1785226280.git.tuhaowen@uniontech.com> |
in_suspend indicates that a hibernation snapshot has been created and is still available. Keep that state consistent with the lifetime of the snapshot memory by clearing in_suspend before swsusp_free() releases it. If image creation fails after in_suspend has been set, hibernation_snapshot() releases the snapshot memory but currently leaves in_suspend set. Preserve its value locally long enough to select the appropriate device resume message, then clear it before releasing the snapshot. Also clear in_suspend before releasing the snapshot after swsusp_write() returns. Acked-by: Rafael J. Wysocki (Intel) <[email protected]> Signed-off-by: Haowen Tu <[email protected]> --- kernel/power/hibernate.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index af8d07bafe02..6d3e637c5a02 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -418,6 +418,7 @@ static void shrink_shmem_memory(void) int hibernation_snapshot(int platform_mode) { pm_message_t msg; + bool snapshot_done; int error; pm_suspend_clear_flags(); @@ -474,15 +475,18 @@ int hibernation_snapshot(int platform_mode) * returns here (1) after the image has been created or the * image creation has failed and (2) after a successful restore. */ + snapshot_done = in_suspend; /* We may need to release the preallocated image pages here. */ - if (error || !in_suspend) + if (error || !snapshot_done) { + in_suspend = 0; swsusp_free(); + } - msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; + msg = snapshot_done ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; dpm_resume(msg); - if (error || !in_suspend) + if (error || !snapshot_done) pm_restore_gfp_mask(); console_resume_all(); @@ -865,6 +869,7 @@ int hibernate(void) pm_pr_dbg("Writing hibernation image.\n"); error = swsusp_write(flags); + in_suspend = 0; swsusp_free(); if (!error) { if (hibernation_mode == HIBERNATION_TEST_RESUME) @@ -872,7 +877,6 @@ int hibernate(void) else power_down(); } - in_suspend = 0; pm_restore_gfp_mask(); } else { pm_pr_dbg("Hibernation image restored successfully.\n"); -- 2.20.1