Commit 0fbeb5a45dccd493c35a68a5548e6a9d9882a791

Authored by Rafael J. Wysocki
Committed by Linus Torvalds
1 parent ed14b52701

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