summaryrefslogtreecommitdiff
path: root/kernel/power/hibernate.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-07-08 11:24:05 (GMT)
committerRafael J. Wysocki <rjw@sisk.pl>2009-09-14 18:26:58 (GMT)
commit64a473cb74a88cb4991edf985d55a266e65292e1 (patch)
tree173402070f904951c9ec16a55e3f96e75289f14c /kernel/power/hibernate.c
parent4bb334353ebd821bc8eeabeb019eaac33c7307df (diff)
downloadlinux-64a473cb74a88cb4991edf985d55a266e65292e1.tar.xz
PM/Hibernate: Do not release preallocated memory unnecessarily (rev. 2)
Since the hibernation code is now going to use allocations of memory to make enough room for the image, it can also use the page frames allocated at this stage as image page frames. The low-level hibernation code needs to be rearranged for this purpose, but it allows us to avoid freeing a great number of pages and allocating these same pages once again later, so it generally is worth doing. [rev. 2: Take highmem into account correctly.] Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r--kernel/power/hibernate.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index ec82025..04b3a83 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -298,8 +298,8 @@ int hibernation_snapshot(int platform_mode)
if (error)
return error;
- /* Free memory before shutting down devices. */
- error = swsusp_shrink_memory();
+ /* Preallocate image memory before shutting down devices. */
+ error = hibernate_preallocate_memory();
if (error)
goto Close;
@@ -315,6 +315,10 @@ int hibernation_snapshot(int platform_mode)
/* Control returns here after successful restore */
Resume_devices:
+ /* We may need to release the preallocated image pages here. */
+ if (error || !in_suspend)
+ swsusp_free();
+
dpm_resume_end(in_suspend ?
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
resume_console();
@@ -578,7 +582,10 @@ int hibernate(void)
goto Thaw;
error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
- if (in_suspend && !error) {
+ if (error)
+ goto Thaw;
+
+ if (in_suspend) {
unsigned int flags = 0;
if (hibernation_mode == HIBERNATION_PLATFORM)
@@ -590,8 +597,8 @@ int hibernate(void)
power_down();
} else {
pr_debug("PM: Image restored successfully.\n");
- swsusp_free();
}
+
Thaw:
thaw_processes();
Finish: