swsusp: do not use page flags

Make swsusp use memory bitmaps instead of page flags for marking 'nosave' and
free pages.  This allows us to 'recycle' two page flags that can be used for
other purposes.  Also, the memory needed to store the bitmaps is allocated
when necessary (ie.  before the suspend) and freed after the resume which is
more reasonable.

The patch is designed to minimize the amount of changes and there are some
nice simplifications and optimizations possible on top of it.  I am going to
implement them separately in the future.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 8df51c2..403bc37 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -139,14 +139,19 @@
 		mdelay(5000);
 		goto Thaw;
 	}
-	/* Free memory before shutting down devices. */
-	error = swsusp_shrink_memory();
+	/* Allocate memory management structures */
+	error = create_basic_memory_bitmaps();
 	if (error)
 		goto Thaw;
 
+	/* Free memory before shutting down devices. */
+	error = swsusp_shrink_memory();
+	if (error)
+		goto Finish;
+
 	error = platform_prepare();
 	if (error)
-		goto Thaw;
+		goto Finish;
 
 	suspend_console();
 	error = device_suspend(PMSG_FREEZE);
@@ -181,7 +186,7 @@
 			power_down();
 		else {
 			swsusp_free();
-			goto Thaw;
+			goto Finish;
 		}
 	} else {
 		pr_debug("PM: Image restored successfully.\n");
@@ -194,6 +199,8 @@
 	platform_finish();
 	device_resume();
 	resume_console();
+ Finish:
+	free_basic_memory_bitmaps();
  Thaw:
 	unprepare_processes();
 	return error;
@@ -239,13 +246,15 @@
 	}
 
 	pr_debug("PM: Checking swsusp image.\n");
-
 	error = swsusp_check();
 	if (error)
-		goto Done;
+		goto Unlock;
+
+	error = create_basic_memory_bitmaps();
+	if (error)
+		goto Unlock;
 
 	pr_debug("PM: Preparing processes for restore.\n");
-
 	error = prepare_processes();
 	if (error) {
 		swsusp_close();
@@ -280,7 +289,9 @@
 	printk(KERN_ERR "PM: Restore failed, recovering.\n");
 	unprepare_processes();
  Done:
+	free_basic_memory_bitmaps();
 	/* For success case, the suspend path will release the lock */
+ Unlock:
 	mutex_unlock(&pm_mutex);
 	pr_debug("PM: Resume from disk failed.\n");
 	return 0;