diff options
| author | Rafael J. Wysocki <rjw@sisk.pl> | 2006-09-26 02:32:50 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:48:59 -0400 |
| commit | cd560bb2f9e2cd451bb3942af43da19632ba4a8e (patch) | |
| tree | bc533af52cc8686f53694cd60a974f7fd3bd80fc /kernel | |
| parent | f6143aa60ed71e58578bc92cc64d98158a694d99 (diff) | |
[PATCH] swsusp: Fix alloc_pagedir
Get rid of the FIXME in kernel/power/snapshot.c#alloc_pagedir() and
simplify the functions called by it.
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')
| -rw-r--r-- | kernel/power/snapshot.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 7ad0c0465524..4ca372f2bc14 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
| @@ -316,12 +316,12 @@ static void free_pagedir(struct pbe *pblist, int clear_nosave_free) | |||
| 316 | * fill_pb_page - Create a list of PBEs on a given memory page | 316 | * fill_pb_page - Create a list of PBEs on a given memory page |
| 317 | */ | 317 | */ |
| 318 | 318 | ||
| 319 | static inline void fill_pb_page(struct pbe *pbpage) | 319 | static inline void fill_pb_page(struct pbe *pbpage, unsigned int n) |
| 320 | { | 320 | { |
| 321 | struct pbe *p; | 321 | struct pbe *p; |
| 322 | 322 | ||
| 323 | p = pbpage; | 323 | p = pbpage; |
| 324 | pbpage += PB_PAGE_SKIP; | 324 | pbpage += n - 1; |
| 325 | do | 325 | do |
| 326 | p->next = p + 1; | 326 | p->next = p + 1; |
| 327 | while (++p < pbpage); | 327 | while (++p < pbpage); |
| @@ -330,24 +330,26 @@ static inline void fill_pb_page(struct pbe *pbpage) | |||
| 330 | /** | 330 | /** |
| 331 | * create_pbe_list - Create a list of PBEs on top of a given chain | 331 | * create_pbe_list - Create a list of PBEs on top of a given chain |
| 332 | * of memory pages allocated with alloc_pagedir() | 332 | * of memory pages allocated with alloc_pagedir() |
| 333 | * | ||
| 334 | * This function assumes that pages allocated by alloc_image_page() will | ||
| 335 | * always be zeroed. | ||
| 333 | */ | 336 | */ |
| 334 | 337 | ||
| 335 | static inline void create_pbe_list(struct pbe *pblist, unsigned int nr_pages) | 338 | static inline void create_pbe_list(struct pbe *pblist, unsigned int nr_pages) |
| 336 | { | 339 | { |
| 337 | struct pbe *pbpage, *p; | 340 | struct pbe *pbpage; |
| 338 | unsigned int num = PBES_PER_PAGE; | 341 | unsigned int num = PBES_PER_PAGE; |
| 339 | 342 | ||
| 340 | for_each_pb_page (pbpage, pblist) { | 343 | for_each_pb_page (pbpage, pblist) { |
| 341 | if (num >= nr_pages) | 344 | if (num >= nr_pages) |
| 342 | break; | 345 | break; |
| 343 | 346 | ||
| 344 | fill_pb_page(pbpage); | 347 | fill_pb_page(pbpage, PBES_PER_PAGE); |
| 345 | num += PBES_PER_PAGE; | 348 | num += PBES_PER_PAGE; |
| 346 | } | 349 | } |
| 347 | if (pbpage) { | 350 | if (pbpage) { |
| 348 | for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++) | 351 | num -= PBES_PER_PAGE; |
| 349 | p->next = p + 1; | 352 | fill_pb_page(pbpage, nr_pages - num); |
| 350 | p->next = NULL; | ||
| 351 | } | 353 | } |
| 352 | } | 354 | } |
| 353 | 355 | ||
| @@ -374,17 +376,17 @@ static struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, | |||
| 374 | return NULL; | 376 | return NULL; |
| 375 | 377 | ||
| 376 | pblist = alloc_image_page(gfp_mask, safe_needed); | 378 | pblist = alloc_image_page(gfp_mask, safe_needed); |
| 377 | /* FIXME: rewrite this ugly loop */ | 379 | pbe = pblist; |
| 378 | for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages; | 380 | for (num = PBES_PER_PAGE; num < nr_pages; num += PBES_PER_PAGE) { |
| 379 | pbe = pbe->next, num += PBES_PER_PAGE) { | 381 | if (!pbe) { |
| 382 | free_pagedir(pblist, 1); | ||
| 383 | return NULL; | ||
| 384 | } | ||
| 380 | pbe += PB_PAGE_SKIP; | 385 | pbe += PB_PAGE_SKIP; |
| 381 | pbe->next = alloc_image_page(gfp_mask, safe_needed); | 386 | pbe->next = alloc_image_page(gfp_mask, safe_needed); |
| 387 | pbe = pbe->next; | ||
| 382 | } | 388 | } |
| 383 | if (!pbe) { /* get_zeroed_page() failed */ | 389 | create_pbe_list(pblist, nr_pages); |
| 384 | free_pagedir(pblist, 1); | ||
| 385 | pblist = NULL; | ||
| 386 | } else | ||
| 387 | create_pbe_list(pblist, nr_pages); | ||
| 388 | return pblist; | 390 | return pblist; |
| 389 | } | 391 | } |
| 390 | 392 | ||
