[PATCH] swsusp: rework swsusp_suspend
authorRafael J. Wysocki <rjw@sisk.pl>
Wed, 9 Nov 2005 05:34:41 +0000 (21:34 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 9 Nov 2005 15:55:52 +0000 (07:55 -0800)
This patch makes only the functions in swsusp.c call functions in snapshot.c
and not both ways.   It also moves the check for available swap out of
swsusp_suspend() which is necessary for separating the swap-handling functions
in swsusp from the core code.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
kernel/power/power.h
kernel/power/snapshot.c
kernel/power/swsusp.c

index 893ee655085c11349c570686e51e939cf7dce81e..6c042b5ee14ba105ce0bf0b53bf8530bf8aee180 100644 (file)
@@ -65,10 +65,8 @@ extern suspend_pagedir_t *pagedir_save;
 extern asmlinkage int swsusp_arch_suspend(void);
 extern asmlinkage int swsusp_arch_resume(void);
 
-extern int restore_highmem(void);
 extern void free_pagedir(struct pbe *pblist);
 extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed);
 extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
 extern void swsusp_free(void);
 extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
-extern int enough_swap(unsigned nr_pages);
index b8a2e9a63206c1de036fe56d54f71dff7785fdf7..4a6dbcefd37875d75e404ae6b5799cec3836a700 100644 (file)
@@ -88,8 +88,7 @@ static int save_highmem_zone(struct zone *zone)
        return 0;
 }
 
-
-static int save_highmem(void)
+int save_highmem(void)
 {
        struct zone *zone;
        int res = 0;
@@ -120,11 +119,7 @@ int restore_highmem(void)
        }
        return 0;
 }
-#else
-static int save_highmem(void) { return 0; }
-int restore_highmem(void) { return 0; }
-#endif /* CONFIG_HIGHMEM */
-
+#endif
 
 static int pfn_is_nosave(unsigned long pfn)
 {
@@ -416,11 +411,6 @@ asmlinkage int swsusp_save(void)
        unsigned int nr_pages;
 
        pr_debug("swsusp: critical section: \n");
-       if (save_highmem()) {
-               printk(KERN_CRIT "swsusp: Not enough free pages for highmem\n");
-               restore_highmem();
-               return -ENOMEM;
-       }
 
        drain_local_pages();
        nr_pages = count_data_pages();
@@ -440,11 +430,6 @@ asmlinkage int swsusp_save(void)
                return -ENOMEM;
        }
 
-       if (!enough_swap(nr_pages)) {
-               printk(KERN_ERR "swsusp: Not enough free swap\n");
-               return -ENOSPC;
-       }
-
        pagedir_nosave = swsusp_alloc(nr_pages);
        if (!pagedir_nosave)
                return -ENOMEM;
index 8511c7f3386a0e655120adb5d507b0d7f6049555..c05f46e7348f54c0658f670370094cb1de30a9f5 100644 (file)
 
 #include "power.h"
 
+#ifdef CONFIG_HIGHMEM
+int save_highmem(void);
+int restore_highmem(void);
+#else
+static int save_highmem(void) { return 0; }
+static int restore_highmem(void) { return 0; }
+#endif
+
 #define CIPHER "aes"
 #define MAXKEY 32
 #define MAXIV  32
@@ -499,6 +507,26 @@ static int write_pagedir(void)
        return error;
 }
 
+/**
+ *     enough_swap - Make sure we have enough swap to save the image.
+ *
+ *     Returns TRUE or FALSE after checking the total amount of swap
+ *     space avaiable.
+ *
+ *     FIXME: si_swapinfo(&i) returns all swap devices information.
+ *     We should only consider resume_device.
+ */
+
+static int enough_swap(unsigned int nr_pages)
+{
+       struct sysinfo i;
+
+       si_swapinfo(&i);
+       pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
+       return i.freeswap > (nr_pages + PAGES_FOR_IO +
+               (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
+}
+
 /**
  *     write_suspend_image - Write entire image and metadata.
  *
@@ -507,6 +535,11 @@ static int write_suspend_image(void)
 {
        int error;
 
+       if (!enough_swap(nr_copy_pages)) {
+               printk(KERN_ERR "swsusp: Not enough free swap\n");
+               return -ENOSPC;
+       }
+
        init_header();
        if ((error = data_write()))
                goto FreeData;
@@ -526,27 +559,6 @@ static int write_suspend_image(void)
        goto Done;
 }
 
-/**
- *     enough_swap - Make sure we have enough swap to save the image.
- *
- *     Returns TRUE or FALSE after checking the total amount of swap
- *     space avaiable.
- *
- *     FIXME: si_swapinfo(&i) returns all swap devices information.
- *     We should only consider resume_device.
- */
-
-int enough_swap(unsigned int nr_pages)
-{
-       struct sysinfo i;
-
-       si_swapinfo(&i);
-       pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
-       return i.freeswap > (nr_pages + PAGES_FOR_IO +
-               (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
-}
-
-
 /* It is important _NOT_ to umount filesystems at this point. We want
  * them synced (in case something goes wrong) but we DO not want to mark
  * filesystem clean: it is not. (And it does not matter, if we resume
@@ -556,12 +568,15 @@ int swsusp_write(void)
 {
        int error;
 
+       if ((error = swsusp_swap_check())) {
+               printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
+               return error;
+       }
        lock_swapdevices();
        error = write_suspend_image();
        /* This will unlock ignored swap devices since writing is finished */
        lock_swapdevices();
        return error;
-
 }
 
 
@@ -569,6 +584,7 @@ int swsusp_write(void)
 int swsusp_suspend(void)
 {
        int error;
+
        if ((error = arch_prepare_suspend()))
                return error;
        local_irq_disable();
@@ -580,15 +596,12 @@ int swsusp_suspend(void)
         */
        if ((error = device_power_down(PMSG_FREEZE))) {
                printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
-               local_irq_enable();
-               return error;
+               goto Enable_irqs;
        }
 
-       if ((error = swsusp_swap_check())) {
-               printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
-               device_power_up();
-               local_irq_enable();
-               return error;
+       if ((error = save_highmem())) {
+               printk(KERN_ERR "swsusp: Not enough free pages for highmem\n");
+               goto Restore_highmem;
        }
 
        save_processor_state();
@@ -596,8 +609,10 @@ int swsusp_suspend(void)
                printk(KERN_ERR "Error %d suspending\n", error);
        /* Restore control flow magically appears here */
        restore_processor_state();
+Restore_highmem:
        restore_highmem();
        device_power_up();
+Enable_irqs:
        local_irq_enable();
        return error;
 }
@@ -804,7 +819,7 @@ static int check_sig(void)
                 * Reset swap signature now.
                 */
                error = bio_write_page(0, &swsusp_header);
-       } else { 
+       } else {
                return -EINVAL;
        }
        if (!error)