static unsigned int nr_copy_pages;
 /* Number of pages needed for saving the original pfns of the image pages */
 static unsigned int nr_meta_pages;
+/*
+ * Numbers of normal and highmem page frames allocated for hibernation image
+ * before suspending devices.
+ */
+unsigned int alloc_normal, alloc_highmem;
+/*
+ * Memory bitmap used for marking saveable pages (during hibernation) or
+ * hibernation image pages (during restore)
+ */
+static struct memory_bitmap orig_bm;
+/*
+ * Memory bitmap used during hibernation for marking allocated page frames that
+ * will contain copies of saveable pages.  During restore it is initially used
+ * for marking hibernation image pages, but then the set bits from it are
+ * duplicated in @orig_bm and it is released.  On highmem systems it is next
+ * used for marking "safe" highmem pages, but it has to be reinitialized for
+ * this purpose.
+ */
+static struct memory_bitmap copy_bm;
 
 /**
  *     swsusp_free - free pages allocated for the suspend.
        nr_meta_pages = 0;
        restore_pblist = NULL;
        buffer = NULL;
+       alloc_normal = 0;
+       alloc_highmem = 0;
 }
 
 /* Helper functions used for the shrinking of memory. */
        unsigned long nr_alloc = 0;
 
        while (nr_pages > 0) {
-               if (!alloc_image_page(mask))
+               struct page *page;
+
+               page = alloc_image_page(mask);
+               if (!page)
                        break;
+               memory_bm_set_bit(©_bm, page_to_pfn(page));
+               if (PageHighMem(page))
+                       alloc_highmem++;
+               else
+                       alloc_normal++;
                nr_pages--;
                nr_alloc++;
        }
 #endif /* CONFIG_HIGHMEM */
 
 /**
- * swsusp_shrink_memory -  Make the kernel release as much memory as needed
+ * free_unnecessary_pages - Release preallocated pages not needed for the image
+ */
+static void free_unnecessary_pages(void)
+{
+       unsigned long save_highmem, to_free_normal, to_free_highmem;
+
+       to_free_normal = alloc_normal - count_data_pages();
+       save_highmem = count_highmem_pages();
+       if (alloc_highmem > save_highmem) {
+               to_free_highmem = alloc_highmem - save_highmem;
+       } else {
+               to_free_highmem = 0;
+               to_free_normal -= save_highmem - alloc_highmem;
+       }
+
+       memory_bm_position_reset(©_bm);
+
+       while (to_free_normal > 0 && to_free_highmem > 0) {
+               unsigned long pfn = memory_bm_next_pfn(©_bm);
+               struct page *page = pfn_to_page(pfn);
+
+               if (PageHighMem(page)) {
+                       if (!to_free_highmem)
+                               continue;
+                       to_free_highmem--;
+                       alloc_highmem--;
+               } else {
+                       if (!to_free_normal)
+                               continue;
+                       to_free_normal--;
+                       alloc_normal--;
+               }
+               memory_bm_clear_bit(©_bm, pfn);
+               swsusp_unset_page_forbidden(page);
+               swsusp_unset_page_free(page);
+               __free_page(page);
+       }
+}
+
+/**
+ * hibernate_preallocate_memory - Preallocate memory for hibernation image
  *
  * To create a hibernation image it is necessary to make a copy of every page
  * frame in use.  We also need a number of page frames to be free during
  * pages in the system is below the requested image size or it is impossible to
  * allocate more memory, whichever happens first.
  */
-int swsusp_shrink_memory(void)
+int hibernate_preallocate_memory(void)
 {
        struct zone *zone;
        unsigned long saveable, size, max_size, count, highmem, pages = 0;
-       unsigned long alloc, pages_highmem;
+       unsigned long alloc, save_highmem, pages_highmem;
        struct timeval start, stop;
-       int error = 0;
+       int error;
 
-       printk(KERN_INFO "PM: Shrinking memory... ");
+       printk(KERN_INFO "PM: Preallocating image memory... ");
        do_gettimeofday(&start);
 
+       error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY);
+       if (error)
+               goto err_out;
+
+       error = memory_bm_create(©_bm, GFP_IMAGE, PG_ANY);
+       if (error)
+               goto err_out;
+
+       alloc_normal = 0;
+       alloc_highmem = 0;
+
        /* Count the number of saveable data pages. */
-       highmem = count_highmem_pages();
+       save_highmem = count_highmem_pages();
        saveable = count_data_pages();
 
        /*
         * number of pages needed for image metadata (size).
         */
        count = saveable;
-       saveable += highmem;
+       saveable += save_highmem;
+       highmem = save_highmem;
        size = 0;
        for_each_populated_zone(zone) {
                size += snapshot_additional_pages(zone);
                size = max_size;
        /*
         * If the maximum is not less than the current number of saveable pages
-        * in memory, we don't need to do anything more.
+        * in memory, allocate page frames for the image and we're done.
         */
-       if (size >= saveable)
+       if (size >= saveable) {
+               pages = preallocate_image_highmem(save_highmem);
+               pages += preallocate_image_memory(saveable - pages);
                goto out;
+       }
 
        /*
         * Let the memory management subsystem know that we're going to need a
        pages_highmem = preallocate_image_highmem(highmem / 2);
        alloc = (count - max_size) - pages_highmem;
        pages = preallocate_image_memory(alloc);
-       if (pages < alloc) {
-               error = -ENOMEM;
-               goto free_out;
-       }
+       if (pages < alloc)
+               goto err_out;
        size = max_size - size;
        alloc = size;
        size = preallocate_highmem_fraction(size, highmem, count);
        pages += preallocate_image_memory(alloc);
        pages += pages_highmem;
 
- free_out:
-       /* Release all of the preallocated page frames. */
-       swsusp_free();
-
-       if (error) {
-               printk(KERN_CONT "\n");
-               return error;
-       }
+       /*
+        * We only need as many page frames for the image as there are saveable
+        * pages in memory, but we have allocated more.  Release the excessive
+        * ones now.
+        */
+       free_unnecessary_pages();
 
  out:
        do_gettimeofday(&stop);
-       printk(KERN_CONT "done (preallocated %lu free pages)\n", pages);
-       swsusp_show_speed(&start, &stop, pages, "Freed");
+       printk(KERN_CONT "done (allocated %lu pages)\n", pages);
+       swsusp_show_speed(&start, &stop, pages, "Allocated");
 
        return 0;
+
+ err_out:
+       printk(KERN_CONT "\n");
+       swsusp_free();
+       return -ENOMEM;
 }
 
 #ifdef CONFIG_HIGHMEM
 
 static unsigned int count_pages_for_highmem(unsigned int nr_highmem)
 {
-       unsigned int free_highmem = count_free_highmem_pages();
+       unsigned int free_highmem = count_free_highmem_pages() + alloc_highmem;
 
        if (free_highmem >= nr_highmem)
                nr_highmem = 0;
 static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem)
 {
        struct zone *zone;
-       unsigned int free = 0, meta = 0;
+       unsigned int free = alloc_normal;
 
-       for_each_zone(zone) {
-               meta += snapshot_additional_pages(zone);
+       for_each_zone(zone)
                if (!is_highmem(zone))
                        free += zone_page_state(zone, NR_FREE_PAGES);
-       }
 
        nr_pages += count_pages_for_highmem(nr_highmem);
-       pr_debug("PM: Normal pages needed: %u + %u + %u, available pages: %u\n",
-               nr_pages, PAGES_FOR_IO, meta, free);
+       pr_debug("PM: Normal pages needed: %u + %u, available pages: %u\n",
+               nr_pages, PAGES_FOR_IO, free);
 
-       return free > nr_pages + PAGES_FOR_IO + meta;
+       return free > nr_pages + PAGES_FOR_IO;
 }
 
 #ifdef CONFIG_HIGHMEM
  */
 
 static inline unsigned int
-alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int nr_highmem)
+alloc_highmem_pages(struct memory_bitmap *bm, unsigned int nr_highmem)
 {
        unsigned int to_alloc = count_free_highmem_pages();
 
 static inline int get_highmem_buffer(int safe_needed) { return 0; }
 
 static inline unsigned int
-alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int n) { return 0; }
+alloc_highmem_pages(struct memory_bitmap *bm, unsigned int n) { return 0; }
 #endif /* CONFIG_HIGHMEM */
 
 /**
 swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm,
                unsigned int nr_pages, unsigned int nr_highmem)
 {
-       int error;
-
-       error = memory_bm_create(orig_bm, GFP_ATOMIC | __GFP_COLD, PG_ANY);
-       if (error)
-               goto Free;
-
-       error = memory_bm_create(copy_bm, GFP_ATOMIC | __GFP_COLD, PG_ANY);
-       if (error)
-               goto Free;
+       int error = 0;
 
        if (nr_highmem > 0) {
                error = get_highmem_buffer(PG_ANY);
                if (error)
-                       goto Free;
-
-               nr_pages += alloc_highmem_image_pages(copy_bm, nr_highmem);
+                       goto err_out;
+               if (nr_highmem > alloc_highmem) {
+                       nr_highmem -= alloc_highmem;
+                       nr_pages += alloc_highmem_pages(copy_bm, nr_highmem);
+               }
        }
-       while (nr_pages-- > 0) {
-               struct page *page = alloc_image_page(GFP_ATOMIC | __GFP_COLD);
-
-               if (!page)
-                       goto Free;
+       if (nr_pages > alloc_normal) {
+               nr_pages -= alloc_normal;
+               while (nr_pages-- > 0) {
+                       struct page *page;
 
-               memory_bm_set_bit(copy_bm, page_to_pfn(page));
+                       page = alloc_image_page(GFP_ATOMIC | __GFP_COLD);
+                       if (!page)
+                               goto err_out;
+                       memory_bm_set_bit(copy_bm, page_to_pfn(page));
+               }
        }
+
        return 0;
 
- Free:
+ err_out:
        swsusp_free();
-       return -ENOMEM;
+       return error;
 }
 
-/* Memory bitmap used for marking saveable pages (during suspend) or the
- * suspend image pages (during resume)
- */
-static struct memory_bitmap orig_bm;
-/* Memory bitmap used on suspend for marking allocated pages that will contain
- * the copies of saveable pages.  During resume it is initially used for
- * marking the suspend image pages, but then its set bits are duplicated in
- * @orig_bm and it is released.  Next, on systems with high memory, it may be
- * used for marking "safe" highmem pages, but it has to be reinitialized for
- * this purpose.
- */
-static struct memory_bitmap copy_bm;
-
 asmlinkage int swsusp_save(void)
 {
        unsigned int nr_pages, nr_highmem;