Commit 0fbeb5a45dccd493c35a68a5548e6a9d9882a791
Committed by
Linus Torvalds
1 parent
ed14b52701
Exists in
master
and in
4 other branches
[PATCH] swsusp: rework swsusp_suspend
This patch makes only the functions in swsusp.c call functions in snapshot.c and not both ways. It also moves the check for available swap out of swsusp_suspend() which is necessary for separating the swap-handling functions in swsusp from the core code. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Cc: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 3 changed files with 47 additions and 49 deletions Side-by-side Diff
kernel/power/power.h
| ... | ... | @@ -65,11 +65,9 @@ |
| 65 | 65 | extern asmlinkage int swsusp_arch_suspend(void); |
| 66 | 66 | extern asmlinkage int swsusp_arch_resume(void); |
| 67 | 67 | |
| 68 | -extern int restore_highmem(void); | |
| 69 | 68 | extern void free_pagedir(struct pbe *pblist); |
| 70 | 69 | extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed); |
| 71 | 70 | extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages); |
| 72 | 71 | extern void swsusp_free(void); |
| 73 | 72 | extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed); |
| 74 | -extern int enough_swap(unsigned nr_pages); |
kernel/power/snapshot.c
| ... | ... | @@ -88,8 +88,7 @@ |
| 88 | 88 | return 0; |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | - | |
| 92 | -static int save_highmem(void) | |
| 91 | +int save_highmem(void) | |
| 93 | 92 | { |
| 94 | 93 | struct zone *zone; |
| 95 | 94 | int res = 0; |
| 96 | 95 | |
| ... | ... | @@ -120,12 +119,8 @@ |
| 120 | 119 | } |
| 121 | 120 | return 0; |
| 122 | 121 | } |
| 123 | -#else | |
| 124 | -static int save_highmem(void) { return 0; } | |
| 125 | -int restore_highmem(void) { return 0; } | |
| 126 | -#endif /* CONFIG_HIGHMEM */ | |
| 122 | +#endif | |
| 127 | 123 | |
| 128 | - | |
| 129 | 124 | static int pfn_is_nosave(unsigned long pfn) |
| 130 | 125 | { |
| 131 | 126 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; |
| ... | ... | @@ -416,11 +411,6 @@ |
| 416 | 411 | unsigned int nr_pages; |
| 417 | 412 | |
| 418 | 413 | pr_debug("swsusp: critical section: \n"); |
| 419 | - if (save_highmem()) { | |
| 420 | - printk(KERN_CRIT "swsusp: Not enough free pages for highmem\n"); | |
| 421 | - restore_highmem(); | |
| 422 | - return -ENOMEM; | |
| 423 | - } | |
| 424 | 414 | |
| 425 | 415 | drain_local_pages(); |
| 426 | 416 | nr_pages = count_data_pages(); |
| ... | ... | @@ -438,11 +428,6 @@ |
| 438 | 428 | if (!enough_free_mem(nr_pages)) { |
| 439 | 429 | printk(KERN_ERR "swsusp: Not enough free memory\n"); |
| 440 | 430 | return -ENOMEM; |
| 441 | - } | |
| 442 | - | |
| 443 | - if (!enough_swap(nr_pages)) { | |
| 444 | - printk(KERN_ERR "swsusp: Not enough free swap\n"); | |
| 445 | - return -ENOSPC; | |
| 446 | 431 | } |
| 447 | 432 | |
| 448 | 433 | pagedir_nosave = swsusp_alloc(nr_pages); |
kernel/power/swsusp.c
| ... | ... | @@ -73,6 +73,14 @@ |
| 73 | 73 | |
| 74 | 74 | #include "power.h" |
| 75 | 75 | |
| 76 | +#ifdef CONFIG_HIGHMEM | |
| 77 | +int save_highmem(void); | |
| 78 | +int restore_highmem(void); | |
| 79 | +#else | |
| 80 | +static int save_highmem(void) { return 0; } | |
| 81 | +static int restore_highmem(void) { return 0; } | |
| 82 | +#endif | |
| 83 | + | |
| 76 | 84 | #define CIPHER "aes" |
| 77 | 85 | #define MAXKEY 32 |
| 78 | 86 | #define MAXIV 32 |
| ... | ... | @@ -500,6 +508,26 @@ |
| 500 | 508 | } |
| 501 | 509 | |
| 502 | 510 | /** |
| 511 | + * enough_swap - Make sure we have enough swap to save the image. | |
| 512 | + * | |
| 513 | + * Returns TRUE or FALSE after checking the total amount of swap | |
| 514 | + * space avaiable. | |
| 515 | + * | |
| 516 | + * FIXME: si_swapinfo(&i) returns all swap devices information. | |
| 517 | + * We should only consider resume_device. | |
| 518 | + */ | |
| 519 | + | |
| 520 | +static int enough_swap(unsigned int nr_pages) | |
| 521 | +{ | |
| 522 | + struct sysinfo i; | |
| 523 | + | |
| 524 | + si_swapinfo(&i); | |
| 525 | + pr_debug("swsusp: available swap: %lu pages\n", i.freeswap); | |
| 526 | + return i.freeswap > (nr_pages + PAGES_FOR_IO + | |
| 527 | + (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE); | |
| 528 | +} | |
| 529 | + | |
| 530 | +/** | |
| 503 | 531 | * write_suspend_image - Write entire image and metadata. |
| 504 | 532 | * |
| 505 | 533 | */ |
| ... | ... | @@ -507,6 +535,11 @@ |
| 507 | 535 | { |
| 508 | 536 | int error; |
| 509 | 537 | |
| 538 | + if (!enough_swap(nr_copy_pages)) { | |
| 539 | + printk(KERN_ERR "swsusp: Not enough free swap\n"); | |
| 540 | + return -ENOSPC; | |
| 541 | + } | |
| 542 | + | |
| 510 | 543 | init_header(); |
| 511 | 544 | if ((error = data_write())) |
| 512 | 545 | goto FreeData; |
| ... | ... | @@ -526,27 +559,6 @@ |
| 526 | 559 | goto Done; |
| 527 | 560 | } |
| 528 | 561 | |
| 529 | -/** | |
| 530 | - * enough_swap - Make sure we have enough swap to save the image. | |
| 531 | - * | |
| 532 | - * Returns TRUE or FALSE after checking the total amount of swap | |
| 533 | - * space avaiable. | |
| 534 | - * | |
| 535 | - * FIXME: si_swapinfo(&i) returns all swap devices information. | |
| 536 | - * We should only consider resume_device. | |
| 537 | - */ | |
| 538 | - | |
| 539 | -int enough_swap(unsigned int nr_pages) | |
| 540 | -{ | |
| 541 | - struct sysinfo i; | |
| 542 | - | |
| 543 | - si_swapinfo(&i); | |
| 544 | - pr_debug("swsusp: available swap: %lu pages\n", i.freeswap); | |
| 545 | - return i.freeswap > (nr_pages + PAGES_FOR_IO + | |
| 546 | - (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE); | |
| 547 | -} | |
| 548 | - | |
| 549 | - | |
| 550 | 562 | /* It is important _NOT_ to umount filesystems at this point. We want |
| 551 | 563 | * them synced (in case something goes wrong) but we DO not want to mark |
| 552 | 564 | * filesystem clean: it is not. (And it does not matter, if we resume |
| 553 | 565 | |
| ... | ... | @@ -556,12 +568,15 @@ |
| 556 | 568 | { |
| 557 | 569 | int error; |
| 558 | 570 | |
| 571 | + if ((error = swsusp_swap_check())) { | |
| 572 | + printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n"); | |
| 573 | + return error; | |
| 574 | + } | |
| 559 | 575 | lock_swapdevices(); |
| 560 | 576 | error = write_suspend_image(); |
| 561 | 577 | /* This will unlock ignored swap devices since writing is finished */ |
| 562 | 578 | lock_swapdevices(); |
| 563 | 579 | return error; |
| 564 | - | |
| 565 | 580 | } |
| 566 | 581 | |
| 567 | 582 | |
| ... | ... | @@ -569,6 +584,7 @@ |
| 569 | 584 | int swsusp_suspend(void) |
| 570 | 585 | { |
| 571 | 586 | int error; |
| 587 | + | |
| 572 | 588 | if ((error = arch_prepare_suspend())) |
| 573 | 589 | return error; |
| 574 | 590 | local_irq_disable(); |
| 575 | 591 | |
| ... | ... | @@ -580,15 +596,12 @@ |
| 580 | 596 | */ |
| 581 | 597 | if ((error = device_power_down(PMSG_FREEZE))) { |
| 582 | 598 | printk(KERN_ERR "Some devices failed to power down, aborting suspend\n"); |
| 583 | - local_irq_enable(); | |
| 584 | - return error; | |
| 599 | + goto Enable_irqs; | |
| 585 | 600 | } |
| 586 | 601 | |
| 587 | - if ((error = swsusp_swap_check())) { | |
| 588 | - printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n"); | |
| 589 | - device_power_up(); | |
| 590 | - local_irq_enable(); | |
| 591 | - return error; | |
| 602 | + if ((error = save_highmem())) { | |
| 603 | + printk(KERN_ERR "swsusp: Not enough free pages for highmem\n"); | |
| 604 | + goto Restore_highmem; | |
| 592 | 605 | } |
| 593 | 606 | |
| 594 | 607 | save_processor_state(); |
| 595 | 608 | |
| ... | ... | @@ -596,8 +609,10 @@ |
| 596 | 609 | printk(KERN_ERR "Error %d suspending\n", error); |
| 597 | 610 | /* Restore control flow magically appears here */ |
| 598 | 611 | restore_processor_state(); |
| 612 | +Restore_highmem: | |
| 599 | 613 | restore_highmem(); |
| 600 | 614 | device_power_up(); |
| 615 | +Enable_irqs: | |
| 601 | 616 | local_irq_enable(); |
| 602 | 617 | return error; |
| 603 | 618 | } |
| ... | ... | @@ -804,7 +819,7 @@ |
| 804 | 819 | * Reset swap signature now. |
| 805 | 820 | */ |
| 806 | 821 | error = bio_write_page(0, &swsusp_header); |
| 807 | - } else { | |
| 822 | + } else { | |
| 808 | 823 | return -EINVAL; |
| 809 | 824 | } |
| 810 | 825 | if (!error) |