Commit ca0aec0f7a94bf9f07fefa8bfd23282d4e8ceb8a
Committed by
Linus Torvalds
1 parent
b3a93a255e
Exists in
master
and in
4 other branches
[PATCH] swsusp: make image size limit tunable
Make the suspend image size limit tunable via /sys/power/image_size. It is necessary for systems on which there is a limited amount of swap available for suspend. It can also be useful for optimizing performance of swsusp on systems with 1 GB of RAM or more. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 5 changed files with 47 additions and 6 deletions Side-by-side Diff
Documentation/power/interface.txt
| ... | ... | @@ -40,4 +40,16 @@ |
| 40 | 40 | |
| 41 | 41 | It will only change to 'firmware' or 'platform' if the system supports |
| 42 | 42 | it. |
| 43 | + | |
| 44 | +/sys/power/image_size controls the size of the image created by | |
| 45 | +the suspend-to-disk mechanism. It can be written a string | |
| 46 | +representing a non-negative integer that will be used as an upper | |
| 47 | +limit of the image size, in megabytes. The suspend-to-disk mechanism will | |
| 48 | +do its best to ensure the image size will not exceed that number. However, | |
| 49 | +if this turns out to be impossible, it will try to suspend anyway using the | |
| 50 | +smallest image possible. In particular, if "0" is written to this file, the | |
| 51 | +suspend image will be as small as possible. | |
| 52 | + | |
| 53 | +Reading from this file will display the current image size limit, which | |
| 54 | +is set to 500 MB by default. |
Documentation/power/swsusp.txt
| ... | ... | @@ -27,6 +27,11 @@ |
| 27 | 27 | |
| 28 | 28 | echo platform > /sys/power/disk; echo disk > /sys/power/state |
| 29 | 29 | |
| 30 | +If you want to limit the suspend image size to N megabytes, do | |
| 31 | + | |
| 32 | +echo N > /sys/power/image_size | |
| 33 | + | |
| 34 | +before suspend (it is limited to 500 MB by default). | |
| 30 | 35 | |
| 31 | 36 | Encrypted suspend image: |
| 32 | 37 | ------------------------ |
kernel/power/disk.c
| ... | ... | @@ -365,9 +365,29 @@ |
| 365 | 365 | |
| 366 | 366 | power_attr(resume); |
| 367 | 367 | |
| 368 | +static ssize_t image_size_show(struct subsystem * subsys, char *buf) | |
| 369 | +{ | |
| 370 | + return sprintf(buf, "%u\n", image_size); | |
| 371 | +} | |
| 372 | + | |
| 373 | +static ssize_t image_size_store(struct subsystem * subsys, const char * buf, size_t n) | |
| 374 | +{ | |
| 375 | + unsigned int size; | |
| 376 | + | |
| 377 | + if (sscanf(buf, "%u", &size) == 1) { | |
| 378 | + image_size = size; | |
| 379 | + return n; | |
| 380 | + } | |
| 381 | + | |
| 382 | + return -EINVAL; | |
| 383 | +} | |
| 384 | + | |
| 385 | +power_attr(image_size); | |
| 386 | + | |
| 368 | 387 | static struct attribute * g[] = { |
| 369 | 388 | &disk_attr.attr, |
| 370 | 389 | &resume_attr.attr, |
| 390 | + &image_size_attr.attr, | |
| 371 | 391 | NULL, |
| 372 | 392 | }; |
| 373 | 393 |
kernel/power/power.h
| ... | ... | @@ -52,11 +52,8 @@ |
| 52 | 52 | extern unsigned int nr_copy_pages; |
| 53 | 53 | extern struct pbe *pagedir_nosave; |
| 54 | 54 | |
| 55 | -/* | |
| 56 | - * Preferred image size in MB (set it to zero to get the smallest | |
| 57 | - * image possible) | |
| 58 | - */ | |
| 59 | -#define IMAGE_SIZE 500 | |
| 55 | +/* Preferred image size in MB (default 500) */ | |
| 56 | +extern unsigned int image_size; | |
| 60 | 57 | |
| 61 | 58 | extern asmlinkage int swsusp_arch_suspend(void); |
| 62 | 59 | extern asmlinkage int swsusp_arch_resume(void); |
kernel/power/swsusp.c
| ... | ... | @@ -69,6 +69,14 @@ |
| 69 | 69 | |
| 70 | 70 | #include "power.h" |
| 71 | 71 | |
| 72 | +/* | |
| 73 | + * Preferred image size in MB (tunable via /sys/power/image_size). | |
| 74 | + * When it is set to N, swsusp will do its best to ensure the image | |
| 75 | + * size will not exceed N MB, but if that is impossible, it will | |
| 76 | + * try to create the smallest image possible. | |
| 77 | + */ | |
| 78 | +unsigned int image_size = 500; | |
| 79 | + | |
| 72 | 80 | #ifdef CONFIG_HIGHMEM |
| 73 | 81 | unsigned int count_highmem_pages(void); |
| 74 | 82 | int save_highmem(void); |
| ... | ... | @@ -647,7 +655,7 @@ |
| 647 | 655 | if (!tmp) |
| 648 | 656 | return -ENOMEM; |
| 649 | 657 | pages += tmp; |
| 650 | - } else if (size > (IMAGE_SIZE * 1024 * 1024) / PAGE_SIZE) { | |
| 658 | + } else if (size > (image_size * 1024 * 1024) / PAGE_SIZE) { | |
| 651 | 659 | tmp = shrink_all_memory(SHRINK_BITE); |
| 652 | 660 | pages += tmp; |
| 653 | 661 | } |