diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2007-05-06 17:50:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-07 15:12:59 -0400 |
commit | 74dfd666de861c97d47bdbd892f6d21b801d0247 (patch) | |
tree | 7200946212cf546f4e5fac31db3dc97dbb144300 /arch/x86_64 | |
parent | 7be9823491ecbaf9700d7d3502cb4b4dd0ed868a (diff) |
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>
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/e820.c | 26 |
1 files changed, 6 insertions, 20 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index be8965427a93..13c6c37610e0 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/kexec.h> | 17 | #include <linux/kexec.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/suspend.h> | ||
21 | #include <linux/pfn.h> | ||
20 | 22 | ||
21 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
22 | #include <asm/page.h> | 24 | #include <asm/page.h> |
@@ -256,22 +258,6 @@ void __init e820_reserve_resources(void) | |||
256 | } | 258 | } |
257 | } | 259 | } |
258 | 260 | ||
259 | /* Mark pages corresponding to given address range as nosave */ | ||
260 | static void __init | ||
261 | e820_mark_nosave_range(unsigned long start, unsigned long end) | ||
262 | { | ||
263 | unsigned long pfn, max_pfn; | ||
264 | |||
265 | if (start >= end) | ||
266 | return; | ||
267 | |||
268 | printk("Nosave address range: %016lx - %016lx\n", start, end); | ||
269 | max_pfn = end >> PAGE_SHIFT; | ||
270 | for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++) | ||
271 | if (pfn_valid(pfn)) | ||
272 | SetPageNosave(pfn_to_page(pfn)); | ||
273 | } | ||
274 | |||
275 | /* | 261 | /* |
276 | * Find the ranges of physical addresses that do not correspond to | 262 | * Find the ranges of physical addresses that do not correspond to |
277 | * e820 RAM areas and mark the corresponding pages as nosave for software | 263 | * e820 RAM areas and mark the corresponding pages as nosave for software |
@@ -290,13 +276,13 @@ void __init e820_mark_nosave_regions(void) | |||
290 | struct e820entry *ei = &e820.map[i]; | 276 | struct e820entry *ei = &e820.map[i]; |
291 | 277 | ||
292 | if (paddr < ei->addr) | 278 | if (paddr < ei->addr) |
293 | e820_mark_nosave_range(paddr, | 279 | register_nosave_region(PFN_DOWN(paddr), |
294 | round_up(ei->addr, PAGE_SIZE)); | 280 | PFN_UP(ei->addr)); |
295 | 281 | ||
296 | paddr = round_down(ei->addr + ei->size, PAGE_SIZE); | 282 | paddr = round_down(ei->addr + ei->size, PAGE_SIZE); |
297 | if (ei->type != E820_RAM) | 283 | if (ei->type != E820_RAM) |
298 | e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE), | 284 | register_nosave_region(PFN_UP(ei->addr), |
299 | paddr); | 285 | PFN_DOWN(paddr)); |
300 | 286 | ||
301 | if (paddr >= (end_pfn << PAGE_SHIFT)) | 287 | if (paddr >= (end_pfn << PAGE_SHIFT)) |
302 | break; | 288 | break; |