=== Diff 1 begin ===============
@@ -1314,6 +1314,12 @@ int hibernate_preallocate_memory(void)
unsigned long alloc, save_highmem, pages_highmem, avail_normal;
struct timeval start, stop;
int error;
+#ifdef CONFIG_HIBERNATION_PREALLOC_MEM_WA
+ unsigned long shrink_pages = 0;
+ int shrink_and_retry_count =
+ CONFIG_HIBERNATION_PREALLOC_MEM_RETRY_COUNT;
+ int shrink_and_retry = 0;
+#endif
printk(KERN_INFO "PM: Preallocating image memory... ");
do_gettimeofday(&start);
@@ -1329,6 +1335,15 @@ int hibernate_preallocate_memory(void)
alloc_normal = 0;
alloc_highmem = 0;
+#ifdef CONFIG_HIBERNATION_PREALLOC_MEM_WA
+shrink_and_retry:
+ if (shrink_and_retry) {
+ shrink_all_memory(shrink_pages +
+ PAGES_FOR_IO +
+ 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE));
+ }
+#endif
+
/* Count the number of saveable data pages. */
save_highmem = count_highmem_pages();
saveable = count_data_pages();
@@ -1367,11 +1382,27 @@ int hibernate_preallocate_memory(void)
* current number of saveable pages in memory, allocate page frames for
* the image and we're done.
*/
+#ifndef CONFIG_HIBERNATION_PREALLOC_MEM_WA
if (size >= saveable) {
pages = preallocate_image_highmem(save_highmem);
pages += preallocate_image_memory(saveable - pages, avail_normal);
goto out;
}
+#else
+ if (size >= saveable || shrink_and_retry) {
+ pages += preallocate_image_highmem(save_highmem);
+ pages += preallocate_image_memory(saveable - pages, avail_normal);
+
+ if (shrink_and_retry < shrink_and_retry_count && pages < saveable) {
+ shrink_and_retry++;
+ shrink_pages = saveable - pages;
+ printk(KERN_WARNING "PM: page allocation failed, shrink
and retry (# %d)\n",
+ shrink_and_retry);
+ goto shrink_and_retry;
+ }
+ goto out;
+ }
+#endif
/* Estimate the minimum size of the image. */
pages = minimum_image_size(saveable);
--
2.4.1
=== Diff 1 end =================
=== Diff 2 begin ===============
@@ -1120,7 +1120,7 @@ void swsusp_free(void)
/* Helper functions used for the shrinking of memory. */
-#define GFP_IMAGE (GFP_KERNEL | __GFP_NOWARN)
+#define GFP_IMAGE (GFP_KERNEL | __GFP_NOWARN | __GFP_MOVABLE)
/**
* preallocate_image_pages - Allocate a number of pages for hibernation image
--
2.4.1
=== Diff 2 end =================
=== Diff 3 begin ===============
@@ -1315,6 +1315,10 @@ int hibernate_preallocate_memory(void)
struct timeval start, stop;
int error;
+printk(KERN_INFO "\n====== mem info 1 begin ======\n");
+show_mem(0);
+printk(KERN_INFO "\n====== mem info 1 end ======\n");
+
printk(KERN_INFO "PM: Preallocating image memory... ");
do_gettimeofday(&start);
@@ -1352,6 +1356,13 @@ int hibernate_preallocate_memory(void)
count += highmem;
count -= totalreserve_pages;
+printk(KERN_INFO "\n\n============\n");
+printk(KERN_INFO "count_highmem_pages() returned %lu\n", save_highmem);
+printk(KERN_INFO "count_data_pages() returned %lu\n", saveable);
+printk(KERN_INFO "number of highmem page frames we can use (highmem)
%lu\n", highmem);
+printk(KERN_INFO "total number of page frames we can use (count)
%lu\n", count);
+printk(KERN_INFO "\n============\n");
+
/* Add number of pages required for page keys (s390 only). */