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 | ||