diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index bbfe472..1130ed0 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -262,10 +262,12 @@ static int create_image(int platform_mode) if (error || hibernation_test(TEST_PLATFORM)) goto Platform_finish; + dbg_log_free_pages(); error = disable_nonboot_cpus(); if (error || hibernation_test(TEST_CPUS) || hibernation_testmode(HIBERNATION_TEST)) goto Enable_cpus; + dbg_log_free_pages(); local_irq_disable(); @@ -496,9 +498,11 @@ int hibernation_platform_enter(void) if (error) goto Platform_finish; + dbg_log_free_pages(); error = disable_nonboot_cpus(); if (error) goto Platform_finish; + dbg_log_free_pages(); local_irq_disable(); sysdev_suspend(PMSG_HIBERNATE); diff --git a/kernel/power/power.h b/kernel/power/power.h index 05611d4..496de77 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -236,3 +236,5 @@ static inline void suspend_thaw_processes(void) { } #endif + +extern void dbg_log_free_pages(void); diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 0985d11..b7241a9 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -64,6 +64,31 @@ struct pbe *restore_pblist; /* Pointer to an auxiliary buffer (1 page) */ static void *buffer; + +void dbg_log_free_pages(void) +{ + unsigned long free = 0, freeable; + struct zone *zone; + + for_each_populated_zone(zone) { + if (is_highmem(zone)) + free += zone_page_state(zone, NR_FREE_PAGES); + else + free += zone_page_state(zone, NR_FREE_PAGES); + } + + freeable = global_page_state(NR_SLAB_RECLAIMABLE) + + global_page_state(NR_ACTIVE_ANON) + + global_page_state(NR_INACTIVE_ANON) + + global_page_state(NR_ACTIVE_FILE) + + global_page_state(NR_INACTIVE_FILE) + - global_page_state(NR_FILE_MAPPED); + + pr_info("PM_D: %ld pages free + %ld freeable (total %ld)\n", + free, freeable, free + freeable); +} + + /** * @safe_needed - on resume, for storing the PBE list and the image, * we can only use memory pages that do not conflict with the pages @@ -1268,7 +1293,7 @@ int hibernate_preallocate_memory(void) struct timeval start, stop; int error; - printk(KERN_INFO "PM: Preallocating image memory... "); + printk(KERN_INFO "PM: Preallocating image memory...\n"); do_gettimeofday(&start); error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY); @@ -1285,6 +1310,8 @@ int hibernate_preallocate_memory(void) /* Count the number of saveable data pages. */ save_highmem = count_highmem_pages(); saveable = count_data_pages(); + pr_info("PM_D: saveable pages: %ld + %ld (highmem) = %ld\n", + saveable, save_highmem, saveable + save_highmem); /* * Compute the total number of page frames we can use (count) and the @@ -1301,29 +1328,50 @@ int hibernate_preallocate_memory(void) else count += zone_page_state(zone, NR_FREE_PAGES); } + pr_info("PM_D: total page count: %ld + %ld (highmem) = %ld\n", + count, highmem, count + highmem); + count += highmem; + + pr_info("PM_D: total page count: %ld - %ld (pgalloc reserve) = %ld\n", + count, totalreserve_pages, count - totalreserve_pages); + count -= totalreserve_pages; + pr_info("PM_D: image metadata needed = %ld\n", size); + /* Compute the maximum number of saveable pages to leave in memory. */ max_size = (count - (size + PAGES_FOR_IO)) / 2 - 2 * SPARE_PAGES; + + pr_info("PM_D: max_size = %ld\n", max_size); + size = DIV_ROUND_UP(image_size, PAGE_SIZE); if (size > max_size) size = max_size; + + pr_info("PM_D: (max) size = %ld\n", size); + /* * If the maximum is not less than the current number of saveable pages * in memory, allocate page frames for the image and we're done. */ if (size >= saveable) { + dbg_log_free_pages(); + pr_info("PM_D: ok, go ahead with full image\n"); pages = preallocate_image_highmem(save_highmem); pages += preallocate_image_memory(saveable - pages); + dbg_log_free_pages(); goto out; } + pr_info("PM_D: need to free some pages\n"); /* Estimate the minimum size of the image. */ pages = minimum_image_size(saveable); if (size < pages) size = min_t(unsigned long, pages, max_size); + pr_info("PM_D: (min) pages = %ld\n", pages); + /* * Let the memory management subsystem know that we're going to need a * large number of page frames to allocate and make it free some memory. @@ -1357,11 +1405,13 @@ int hibernate_preallocate_memory(void) * pages in memory, but we have allocated more. Release the excessive * ones now. */ + dbg_log_free_pages(); free_unnecessary_pages(); - + dbg_log_free_pages(); out: do_gettimeofday(&stop); - printk(KERN_CONT "done (allocated %lu pages)\n", pages); + printk(KERN_INFO "PM: done (allocated %lu pages)\n", pages); + swsusp_show_speed(&start, &stop, pages, "Allocated"); return 0;