diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2006-01-06 03:13:05 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:40 -0500 |
commit | 7088a5c00103ef48782d6c359cd12b13a10666e6 (patch) | |
tree | b731c8af48e00c0ec88bbe57b6b2a2c1ec20fbde /kernel/power/snapshot.c | |
parent | f2d97f02961e8b1f8a24befb88ab0e5c886586ff (diff) |
[PATCH] swsusp: introduce the swap map structure
This patch introduces the swap map structure that can be used by swsusp for
keeping tracks of data pages written to the swap. The structure itself is
described in a comment within the patch.
The overall idea is to reduce the amount of metadata written to the swap and
to write and read the image pages sequentially, in a file-alike way. This
makes the swap-handling part of swsusp fairly independent of its
snapshot-handling part and will hopefully allow us to completely separate
these two parts in the future.
This patch is needed to remove the suspend image size limit imposed by the
limited size of the swsusp_info structure, which is essential for x86-64
systems with more than 512 MB of RAM.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/power/snapshot.c')
-rw-r--r-- | kernel/power/snapshot.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 4a6dbcefd378..152d56cdf017 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -33,6 +33,9 @@ | |||
33 | 33 | ||
34 | #include "power.h" | 34 | #include "power.h" |
35 | 35 | ||
36 | struct pbe *pagedir_nosave; | ||
37 | unsigned int nr_copy_pages; | ||
38 | |||
36 | #ifdef CONFIG_HIGHMEM | 39 | #ifdef CONFIG_HIGHMEM |
37 | struct highmem_page { | 40 | struct highmem_page { |
38 | char *data; | 41 | char *data; |
@@ -244,7 +247,7 @@ static inline void fill_pb_page(struct pbe *pbpage) | |||
244 | * of memory pages allocated with alloc_pagedir() | 247 | * of memory pages allocated with alloc_pagedir() |
245 | */ | 248 | */ |
246 | 249 | ||
247 | void create_pbe_list(struct pbe *pblist, unsigned int nr_pages) | 250 | static inline void create_pbe_list(struct pbe *pblist, unsigned int nr_pages) |
248 | { | 251 | { |
249 | struct pbe *pbpage, *p; | 252 | struct pbe *pbpage, *p; |
250 | unsigned int num = PBES_PER_PAGE; | 253 | unsigned int num = PBES_PER_PAGE; |
@@ -261,7 +264,6 @@ void create_pbe_list(struct pbe *pblist, unsigned int nr_pages) | |||
261 | p->next = p + 1; | 264 | p->next = p + 1; |
262 | p->next = NULL; | 265 | p->next = NULL; |
263 | } | 266 | } |
264 | pr_debug("create_pbe_list(): initialized %d PBEs\n", num); | ||
265 | } | 267 | } |
266 | 268 | ||
267 | /** | 269 | /** |
@@ -332,7 +334,8 @@ struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed | |||
332 | if (!pbe) { /* get_zeroed_page() failed */ | 334 | if (!pbe) { /* get_zeroed_page() failed */ |
333 | free_pagedir(pblist); | 335 | free_pagedir(pblist); |
334 | pblist = NULL; | 336 | pblist = NULL; |
335 | } | 337 | } else |
338 | create_pbe_list(pblist, nr_pages); | ||
336 | return pblist; | 339 | return pblist; |
337 | } | 340 | } |
338 | 341 | ||
@@ -395,7 +398,6 @@ static struct pbe *swsusp_alloc(unsigned int nr_pages) | |||
395 | printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); | 398 | printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); |
396 | return NULL; | 399 | return NULL; |
397 | } | 400 | } |
398 | create_pbe_list(pblist, nr_pages); | ||
399 | 401 | ||
400 | if (alloc_data_pages(pblist, GFP_ATOMIC | __GFP_COLD, 0)) { | 402 | if (alloc_data_pages(pblist, GFP_ATOMIC | __GFP_COLD, 0)) { |
401 | printk(KERN_ERR "suspend: Allocating image pages failed.\n"); | 403 | printk(KERN_ERR "suspend: Allocating image pages failed.\n"); |
@@ -421,10 +423,6 @@ asmlinkage int swsusp_save(void) | |||
421 | (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE, | 423 | (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE, |
422 | PAGES_FOR_IO, nr_free_pages()); | 424 | PAGES_FOR_IO, nr_free_pages()); |
423 | 425 | ||
424 | /* This is needed because of the fixed size of swsusp_info */ | ||
425 | if (MAX_PBES < (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE) | ||
426 | return -ENOSPC; | ||
427 | |||
428 | if (!enough_free_mem(nr_pages)) { | 426 | if (!enough_free_mem(nr_pages)) { |
429 | printk(KERN_ERR "swsusp: Not enough free memory\n"); | 427 | printk(KERN_ERR "swsusp: Not enough free memory\n"); |
430 | return -ENOMEM; | 428 | return -ENOMEM; |