Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 54262
b: refs/heads/master
c: 74dfd66
h: refs/heads/master
v: v3
  • Loading branch information
Rafael J. Wysocki authored and Linus Torvalds committed May 7, 2007
1 parent 35ded4e commit 38a4612
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 83 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7be9823491ecbaf9700d7d3502cb4b4dd0ed868a
refs/heads/master: 74dfd666de861c97d47bdbd892f6d21b801d0247
26 changes: 6 additions & 20 deletions trunk/arch/x86_64/kernel/e820.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <linux/kexec.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/suspend.h>
#include <linux/pfn.h>

#include <asm/pgtable.h>
#include <asm/page.h>
Expand Down Expand Up @@ -256,22 +258,6 @@ void __init e820_reserve_resources(void)
}
}

/* Mark pages corresponding to given address range as nosave */
static void __init
e820_mark_nosave_range(unsigned long start, unsigned long end)
{
unsigned long pfn, max_pfn;

if (start >= end)
return;

printk("Nosave address range: %016lx - %016lx\n", start, end);
max_pfn = end >> PAGE_SHIFT;
for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++)
if (pfn_valid(pfn))
SetPageNosave(pfn_to_page(pfn));
}

/*
* Find the ranges of physical addresses that do not correspond to
* e820 RAM areas and mark the corresponding pages as nosave for software
Expand All @@ -290,13 +276,13 @@ void __init e820_mark_nosave_regions(void)
struct e820entry *ei = &e820.map[i];

if (paddr < ei->addr)
e820_mark_nosave_range(paddr,
round_up(ei->addr, PAGE_SIZE));
register_nosave_region(PFN_DOWN(paddr),
PFN_UP(ei->addr));

paddr = round_down(ei->addr + ei->size, PAGE_SIZE);
if (ei->type != E820_RAM)
e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE),
paddr);
register_nosave_region(PFN_UP(ei->addr),
PFN_DOWN(paddr));

if (paddr >= (end_pfn << PAGE_SHIFT))
break;
Expand Down
58 changes: 18 additions & 40 deletions trunk/include/linux/suspend.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,63 +24,41 @@ struct pbe {
extern void drain_local_pages(void);
extern void mark_free_pages(struct zone *zone);

#ifdef CONFIG_PM
/* kernel/power/swsusp.c */
extern int software_suspend(void);

#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
#if defined(CONFIG_PM) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
extern int pm_prepare_console(void);
extern void pm_restore_console(void);
#else
static inline int pm_prepare_console(void) { return 0; }
static inline void pm_restore_console(void) {}
#endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */
#endif

#if defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND)
/* kernel/power/swsusp.c */
extern int software_suspend(void);
/* kernel/power/snapshot.c */
extern void __init register_nosave_region(unsigned long, unsigned long);
extern int swsusp_page_is_forbidden(struct page *);
extern void swsusp_set_page_free(struct page *);
extern void swsusp_unset_page_free(struct page *);
extern unsigned long get_safe_page(gfp_t gfp_mask);
#else
static inline int software_suspend(void)
{
printk("Warning: fake suspend called\n");
return -ENOSYS;
}
#endif /* CONFIG_PM */

static inline void register_nosave_region(unsigned long b, unsigned long e) {}
static inline int swsusp_page_is_forbidden(struct page *p) { return 0; }
static inline void swsusp_set_page_free(struct page *p) {}
static inline void swsusp_unset_page_free(struct page *p) {}
#endif /* defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND) */

void save_processor_state(void);
void restore_processor_state(void);
struct saved_context;
void __save_processor_state(struct saved_context *ctxt);
void __restore_processor_state(struct saved_context *ctxt);
unsigned long get_safe_page(gfp_t gfp_mask);

/* Page management functions for the software suspend (swsusp) */

static inline void swsusp_set_page_forbidden(struct page *page)
{
SetPageNosave(page);
}

static inline int swsusp_page_is_forbidden(struct page *page)
{
return PageNosave(page);
}

static inline void swsusp_unset_page_forbidden(struct page *page)
{
ClearPageNosave(page);
}

static inline void swsusp_set_page_free(struct page *page)
{
SetPageNosaveFree(page);
}

static inline int swsusp_page_is_free(struct page *page)
{
return PageNosaveFree(page);
}

static inline void swsusp_unset_page_free(struct page *page)
{
ClearPageNosaveFree(page);
}

/*
* XXX: We try to keep some more pages free so that I/O operations succeed
Expand Down
23 changes: 17 additions & 6 deletions trunk/kernel/power/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,19 @@ int pm_suspend_disk(void)
mdelay(5000);
goto Thaw;
}
/* 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 Thaw;
goto Finish;

error = platform_prepare();
if (error)
goto Thaw;
goto Finish;

suspend_console();
error = device_suspend(PMSG_FREEZE);
Expand Down Expand Up @@ -181,7 +186,7 @@ int pm_suspend_disk(void)
power_down();
else {
swsusp_free();
goto Thaw;
goto Finish;
}
} else {
pr_debug("PM: Image restored successfully.\n");
Expand All @@ -194,6 +199,8 @@ int pm_suspend_disk(void)
platform_finish();
device_resume();
resume_console();
Finish:
free_basic_memory_bitmaps();
Thaw:
unprepare_processes();
return error;
Expand Down Expand Up @@ -239,13 +246,15 @@ static int software_resume(void)
}

pr_debug("PM: Checking swsusp image.\n");

error = swsusp_check();
if (error)
goto Done;
goto Unlock;

pr_debug("PM: Preparing processes for restore.\n");
error = create_basic_memory_bitmaps();
if (error)
goto Unlock;

pr_debug("PM: Preparing processes for restore.\n");
error = prepare_processes();
if (error) {
swsusp_close();
Expand Down Expand Up @@ -280,7 +289,9 @@ static int software_resume(void)
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;
Expand Down
2 changes: 2 additions & 0 deletions trunk/kernel/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ static int enter_state(suspend_state_t state)
return error;
}

#ifdef CONFIG_SOFTWARE_SUSPEND
/*
* This is main interface to the outside world. It needs to be
* called from process context.
Expand All @@ -252,6 +253,7 @@ int software_suspend(void)
{
return enter_state(PM_SUSPEND_DISK);
}
#endif


/**
Expand Down
2 changes: 2 additions & 0 deletions trunk/kernel/power/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ extern sector_t swsusp_resume_block;
extern asmlinkage int swsusp_arch_suspend(void);
extern asmlinkage int swsusp_arch_resume(void);

extern int create_basic_memory_bitmaps(void);
extern void free_basic_memory_bitmaps(void);
extern unsigned int count_data_pages(void);

/**
Expand Down
Loading

0 comments on commit 38a4612

Please sign in to comment.