[PATCH] swsusp: rework swsusp_suspend
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>
This commit is contained in:
committed by
Linus Torvalds
parent
ed14b52701
commit
0fbeb5a45d
@@ -65,10 +65,8 @@ extern suspend_pagedir_t *pagedir_save;
|
|||||||
extern asmlinkage int swsusp_arch_suspend(void);
|
extern asmlinkage int swsusp_arch_suspend(void);
|
||||||
extern asmlinkage int swsusp_arch_resume(void);
|
extern asmlinkage int swsusp_arch_resume(void);
|
||||||
|
|
||||||
extern int restore_highmem(void);
|
|
||||||
extern void free_pagedir(struct pbe *pblist);
|
extern void free_pagedir(struct pbe *pblist);
|
||||||
extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed);
|
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 create_pbe_list(struct pbe *pblist, unsigned nr_pages);
|
||||||
extern void swsusp_free(void);
|
extern void swsusp_free(void);
|
||||||
extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
|
extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
|
||||||
extern int enough_swap(unsigned nr_pages);
|
|
||||||
|
@@ -88,8 +88,7 @@ static int save_highmem_zone(struct zone *zone)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int save_highmem(void)
|
||||||
static int save_highmem(void)
|
|
||||||
{
|
{
|
||||||
struct zone *zone;
|
struct zone *zone;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
@@ -120,11 +119,7 @@ int restore_highmem(void)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
static int save_highmem(void) { return 0; }
|
|
||||||
int restore_highmem(void) { return 0; }
|
|
||||||
#endif /* CONFIG_HIGHMEM */
|
|
||||||
|
|
||||||
|
|
||||||
static int pfn_is_nosave(unsigned long pfn)
|
static int pfn_is_nosave(unsigned long pfn)
|
||||||
{
|
{
|
||||||
@@ -416,11 +411,6 @@ asmlinkage int swsusp_save(void)
|
|||||||
unsigned int nr_pages;
|
unsigned int nr_pages;
|
||||||
|
|
||||||
pr_debug("swsusp: critical section: \n");
|
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();
|
drain_local_pages();
|
||||||
nr_pages = count_data_pages();
|
nr_pages = count_data_pages();
|
||||||
@@ -440,11 +430,6 @@ asmlinkage int swsusp_save(void)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enough_swap(nr_pages)) {
|
|
||||||
printk(KERN_ERR "swsusp: Not enough free swap\n");
|
|
||||||
return -ENOSPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
pagedir_nosave = swsusp_alloc(nr_pages);
|
pagedir_nosave = swsusp_alloc(nr_pages);
|
||||||
if (!pagedir_nosave)
|
if (!pagedir_nosave)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@@ -73,6 +73,14 @@
|
|||||||
|
|
||||||
#include "power.h"
|
#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 CIPHER "aes"
|
||||||
#define MAXKEY 32
|
#define MAXKEY 32
|
||||||
#define MAXIV 32
|
#define MAXIV 32
|
||||||
@@ -499,6 +507,26 @@ static int write_pagedir(void)
|
|||||||
return error;
|
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.
|
* write_suspend_image - Write entire image and metadata.
|
||||||
*
|
*
|
||||||
@@ -507,6 +535,11 @@ static int write_suspend_image(void)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
if (!enough_swap(nr_copy_pages)) {
|
||||||
|
printk(KERN_ERR "swsusp: Not enough free swap\n");
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
init_header();
|
init_header();
|
||||||
if ((error = data_write()))
|
if ((error = data_write()))
|
||||||
goto FreeData;
|
goto FreeData;
|
||||||
@@ -526,27 +559,6 @@ static int write_suspend_image(void)
|
|||||||
goto Done;
|
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
|
/* 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
|
* 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
|
* filesystem clean: it is not. (And it does not matter, if we resume
|
||||||
@@ -556,12 +568,15 @@ int swsusp_write(void)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
if ((error = swsusp_swap_check())) {
|
||||||
|
printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
lock_swapdevices();
|
lock_swapdevices();
|
||||||
error = write_suspend_image();
|
error = write_suspend_image();
|
||||||
/* This will unlock ignored swap devices since writing is finished */
|
/* This will unlock ignored swap devices since writing is finished */
|
||||||
lock_swapdevices();
|
lock_swapdevices();
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -569,6 +584,7 @@ int swsusp_write(void)
|
|||||||
int swsusp_suspend(void)
|
int swsusp_suspend(void)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((error = arch_prepare_suspend()))
|
if ((error = arch_prepare_suspend()))
|
||||||
return error;
|
return error;
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
@@ -580,15 +596,12 @@ int swsusp_suspend(void)
|
|||||||
*/
|
*/
|
||||||
if ((error = device_power_down(PMSG_FREEZE))) {
|
if ((error = device_power_down(PMSG_FREEZE))) {
|
||||||
printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
|
printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
|
||||||
local_irq_enable();
|
goto Enable_irqs;
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = swsusp_swap_check())) {
|
if ((error = save_highmem())) {
|
||||||
printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
|
printk(KERN_ERR "swsusp: Not enough free pages for highmem\n");
|
||||||
device_power_up();
|
goto Restore_highmem;
|
||||||
local_irq_enable();
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
save_processor_state();
|
save_processor_state();
|
||||||
@@ -596,8 +609,10 @@ int swsusp_suspend(void)
|
|||||||
printk(KERN_ERR "Error %d suspending\n", error);
|
printk(KERN_ERR "Error %d suspending\n", error);
|
||||||
/* Restore control flow magically appears here */
|
/* Restore control flow magically appears here */
|
||||||
restore_processor_state();
|
restore_processor_state();
|
||||||
|
Restore_highmem:
|
||||||
restore_highmem();
|
restore_highmem();
|
||||||
device_power_up();
|
device_power_up();
|
||||||
|
Enable_irqs:
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -804,7 +819,7 @@ static int check_sig(void)
|
|||||||
* Reset swap signature now.
|
* Reset swap signature now.
|
||||||
*/
|
*/
|
||||||
error = bio_write_page(0, &swsusp_header);
|
error = bio_write_page(0, &swsusp_header);
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (!error)
|
if (!error)
|
||||||
|
Reference in New Issue
Block a user