Commit 7a7b99bf authored by Luigi Semenzato's avatar Luigi Semenzato Committed by Rafael J. Wysocki

PM: hibernate: Add more logging on hibernation failure

Hibernation fails when the kernel cannot allocate enough memory
to copy all pages of RAM in use.

Ensure that the failure reason is clearly logged, and clearly
attributable to the hibernation module.
Signed-off-by: default avatarLuigi Semenzato <semenzato@google.com>
[ rjw: Subject & changelog ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 809ed78a
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Copyright (C) 2012 Bojan Smojver <bojan@rexursive.com> * Copyright (C) 2012 Bojan Smojver <bojan@rexursive.com>
*/ */
#define pr_fmt(fmt) "PM: " fmt #define pr_fmt(fmt) "PM: hibernation: " fmt
#include <linux/export.h> #include <linux/export.h>
#include <linux/suspend.h> #include <linux/suspend.h>
...@@ -106,7 +106,7 @@ EXPORT_SYMBOL(system_entering_hibernation); ...@@ -106,7 +106,7 @@ EXPORT_SYMBOL(system_entering_hibernation);
#ifdef CONFIG_PM_DEBUG #ifdef CONFIG_PM_DEBUG
static void hibernation_debug_sleep(void) static void hibernation_debug_sleep(void)
{ {
pr_info("hibernation debug: Waiting for 5 seconds.\n"); pr_info("debug: Waiting for 5 seconds.\n");
mdelay(5000); mdelay(5000);
} }
...@@ -277,7 +277,7 @@ static int create_image(int platform_mode) ...@@ -277,7 +277,7 @@ static int create_image(int platform_mode)
error = dpm_suspend_end(PMSG_FREEZE); error = dpm_suspend_end(PMSG_FREEZE);
if (error) { if (error) {
pr_err("Some devices failed to power down, aborting hibernation\n"); pr_err("Some devices failed to power down, aborting\n");
return error; return error;
} }
...@@ -295,7 +295,7 @@ static int create_image(int platform_mode) ...@@ -295,7 +295,7 @@ static int create_image(int platform_mode)
error = syscore_suspend(); error = syscore_suspend();
if (error) { if (error) {
pr_err("Some system devices failed to power down, aborting hibernation\n"); pr_err("Some system devices failed to power down, aborting\n");
goto Enable_irqs; goto Enable_irqs;
} }
...@@ -310,7 +310,7 @@ static int create_image(int platform_mode) ...@@ -310,7 +310,7 @@ static int create_image(int platform_mode)
restore_processor_state(); restore_processor_state();
trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, false); trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, false);
if (error) if (error)
pr_err("Error %d creating hibernation image\n", error); pr_err("Error %d creating image\n", error);
if (!in_suspend) { if (!in_suspend) {
events_check_enabled = false; events_check_enabled = false;
...@@ -680,7 +680,7 @@ static int load_image_and_restore(void) ...@@ -680,7 +680,7 @@ static int load_image_and_restore(void)
if (!error) if (!error)
hibernation_restore(flags & SF_PLATFORM_MODE); hibernation_restore(flags & SF_PLATFORM_MODE);
pr_err("Failed to load hibernation image, recovering.\n"); pr_err("Failed to load image, recovering.\n");
swsusp_free(); swsusp_free();
free_basic_memory_bitmaps(); free_basic_memory_bitmaps();
Unlock: Unlock:
...@@ -743,7 +743,7 @@ int hibernate(void) ...@@ -743,7 +743,7 @@ int hibernate(void)
else else
flags |= SF_CRC32_MODE; flags |= SF_CRC32_MODE;
pm_pr_dbg("Writing image.\n"); pm_pr_dbg("Writing hibernation image.\n");
error = swsusp_write(flags); error = swsusp_write(flags);
swsusp_free(); swsusp_free();
if (!error) { if (!error) {
...@@ -755,7 +755,7 @@ int hibernate(void) ...@@ -755,7 +755,7 @@ int hibernate(void)
in_suspend = 0; in_suspend = 0;
pm_restore_gfp_mask(); pm_restore_gfp_mask();
} else { } else {
pm_pr_dbg("Image restored successfully.\n"); pm_pr_dbg("Hibernation image restored successfully.\n");
} }
Free_bitmaps: Free_bitmaps:
...@@ -894,7 +894,7 @@ static int software_resume(void) ...@@ -894,7 +894,7 @@ static int software_resume(void)
goto Close_Finish; goto Close_Finish;
} }
pm_pr_dbg("Preparing processes for restore.\n"); pm_pr_dbg("Preparing processes for hibernation restore.\n");
error = freeze_processes(); error = freeze_processes();
if (error) if (error)
goto Close_Finish; goto Close_Finish;
...@@ -903,7 +903,7 @@ static int software_resume(void) ...@@ -903,7 +903,7 @@ static int software_resume(void)
Finish: Finish:
__pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL); __pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
pm_restore_console(); pm_restore_console();
pr_info("resume from hibernation failed (%d)\n", error); pr_info("resume failed (%d)\n", error);
atomic_inc(&snapshot_device_available); atomic_inc(&snapshot_device_available);
/* For success case, the suspend path will release the lock */ /* For success case, the suspend path will release the lock */
Unlock: Unlock:
...@@ -1068,7 +1068,8 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, ...@@ -1068,7 +1068,8 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
lock_system_sleep(); lock_system_sleep();
swsusp_resume_device = res; swsusp_resume_device = res;
unlock_system_sleep(); unlock_system_sleep();
pm_pr_dbg("Configured resume from disk to %u\n", swsusp_resume_device); pm_pr_dbg("Configured hibernation resume from disk to %u\n",
swsusp_resume_device);
noresume = 0; noresume = 0;
software_resume(); software_resume();
return n; return n;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
*/ */
#define pr_fmt(fmt) "PM: " fmt #define pr_fmt(fmt) "PM: hibernation: " fmt
#include <linux/version.h> #include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -1703,16 +1703,20 @@ int hibernate_preallocate_memory(void) ...@@ -1703,16 +1703,20 @@ int hibernate_preallocate_memory(void)
ktime_t start, stop; ktime_t start, stop;
int error; int error;
pr_info("Preallocating image memory... "); pr_info("Preallocating image memory\n");
start = ktime_get(); start = ktime_get();
error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY); error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY);
if (error) if (error) {
pr_err("Cannot allocate original bitmap\n");
goto err_out; goto err_out;
}
error = memory_bm_create(&copy_bm, GFP_IMAGE, PG_ANY); error = memory_bm_create(&copy_bm, GFP_IMAGE, PG_ANY);
if (error) if (error) {
pr_err("Cannot allocate copy bitmap\n");
goto err_out; goto err_out;
}
alloc_normal = 0; alloc_normal = 0;
alloc_highmem = 0; alloc_highmem = 0;
...@@ -1802,8 +1806,11 @@ int hibernate_preallocate_memory(void) ...@@ -1802,8 +1806,11 @@ int hibernate_preallocate_memory(void)
alloc -= pages; alloc -= pages;
pages += pages_highmem; pages += pages_highmem;
pages_highmem = preallocate_image_highmem(alloc); pages_highmem = preallocate_image_highmem(alloc);
if (pages_highmem < alloc) if (pages_highmem < alloc) {
pr_err("Image allocation is %lu pages short\n",
alloc - pages_highmem);
goto err_out; goto err_out;
}
pages += pages_highmem; pages += pages_highmem;
/* /*
* size is the desired number of saveable pages to leave in * size is the desired number of saveable pages to leave in
...@@ -1834,13 +1841,12 @@ int hibernate_preallocate_memory(void) ...@@ -1834,13 +1841,12 @@ int hibernate_preallocate_memory(void)
out: out:
stop = ktime_get(); stop = ktime_get();
pr_cont("done (allocated %lu pages)\n", pages); pr_info("Allocated %lu pages for shapshot\n", pages);
swsusp_show_speed(start, stop, pages, "Allocated"); swsusp_show_speed(start, stop, pages, "Allocated");
return 0; return 0;
err_out: err_out:
pr_cont("\n");
swsusp_free(); swsusp_free();
return -ENOMEM; return -ENOMEM;
} }
...@@ -1974,7 +1980,7 @@ asmlinkage __visible int swsusp_save(void) ...@@ -1974,7 +1980,7 @@ asmlinkage __visible int swsusp_save(void)
{ {
unsigned int nr_pages, nr_highmem; unsigned int nr_pages, nr_highmem;
pr_info("Creating hibernation image:\n"); pr_info("Creating image:\n");
drain_local_pages(NULL); drain_local_pages(NULL);
nr_pages = count_data_pages(); nr_pages = count_data_pages();
...@@ -2008,7 +2014,7 @@ asmlinkage __visible int swsusp_save(void) ...@@ -2008,7 +2014,7 @@ asmlinkage __visible int swsusp_save(void)
nr_copy_pages = nr_pages; nr_copy_pages = nr_pages;
nr_meta_pages = DIV_ROUND_UP(nr_pages * sizeof(long), PAGE_SIZE); nr_meta_pages = DIV_ROUND_UP(nr_pages * sizeof(long), PAGE_SIZE);
pr_info("Hibernation image created (%d pages copied)\n", nr_pages); pr_info("Image created (%d pages copied)\n", nr_pages);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment