[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.