aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/swap.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/swap.c')
-rw-r--r--kernel/power/swap.c336
1 files changed, 318 insertions, 18 deletions
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index e6a5bdf61a37..7c97c3a0eee3 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -6,6 +6,7 @@
6 * 6 *
7 * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz> 7 * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz>
8 * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> 8 * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
9 * Copyright (C) 2010 Bojan Smojver <bojan@rexursive.com>
9 * 10 *
10 * This file is released under the GPLv2. 11 * This file is released under the GPLv2.
11 * 12 *
@@ -24,10 +25,12 @@
24#include <linux/swapops.h> 25#include <linux/swapops.h>
25#include <linux/pm.h> 26#include <linux/pm.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/lzo.h>
29#include <linux/vmalloc.h>
27 30
28#include "power.h" 31#include "power.h"
29 32
30#define SWSUSP_SIG "S1SUSPEND" 33#define HIBERNATE_SIG "S1SUSPEND"
31 34
32/* 35/*
33 * The swap map is a data structure used for keeping track of each page 36 * The swap map is a data structure used for keeping track of each page
@@ -193,7 +196,7 @@ static int mark_swapfiles(struct swap_map_handle *handle, unsigned int flags)
193 if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) || 196 if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) ||
194 !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) { 197 !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) {
195 memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10); 198 memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10);
196 memcpy(swsusp_header->sig,SWSUSP_SIG, 10); 199 memcpy(swsusp_header->sig, HIBERNATE_SIG, 10);
197 swsusp_header->image = handle->first_sector; 200 swsusp_header->image = handle->first_sector;
198 swsusp_header->flags = flags; 201 swsusp_header->flags = flags;
199 error = hib_bio_write_page(swsusp_resume_block, 202 error = hib_bio_write_page(swsusp_resume_block,
@@ -221,7 +224,7 @@ static int swsusp_swap_check(void)
221 return res; 224 return res;
222 225
223 root_swap = res; 226 root_swap = res;
224 res = blkdev_get(hib_resume_bdev, FMODE_WRITE); 227 res = blkdev_get(hib_resume_bdev, FMODE_WRITE, NULL);
225 if (res) 228 if (res)
226 return res; 229 return res;
227 230
@@ -249,7 +252,7 @@ static int write_page(void *buf, sector_t offset, struct bio **bio_chain)
249 if (bio_chain) { 252 if (bio_chain) {
250 src = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH); 253 src = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
251 if (src) { 254 if (src) {
252 memcpy(src, buf, PAGE_SIZE); 255 copy_page(src, buf);
253 } else { 256 } else {
254 WARN_ON_ONCE(1); 257 WARN_ON_ONCE(1);
255 bio_chain = NULL; /* Go synchronous */ 258 bio_chain = NULL; /* Go synchronous */
@@ -323,7 +326,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf,
323 error = write_page(handle->cur, handle->cur_swap, NULL); 326 error = write_page(handle->cur, handle->cur_swap, NULL);
324 if (error) 327 if (error)
325 goto out; 328 goto out;
326 memset(handle->cur, 0, PAGE_SIZE); 329 clear_page(handle->cur);
327 handle->cur_swap = offset; 330 handle->cur_swap = offset;
328 handle->k = 0; 331 handle->k = 0;
329 } 332 }
@@ -357,6 +360,18 @@ static int swap_writer_finish(struct swap_map_handle *handle,
357 return error; 360 return error;
358} 361}
359 362
363/* We need to remember how much compressed data we need to read. */
364#define LZO_HEADER sizeof(size_t)
365
366/* Number of pages/bytes we'll compress at one time. */
367#define LZO_UNC_PAGES 32
368#define LZO_UNC_SIZE (LZO_UNC_PAGES * PAGE_SIZE)
369
370/* Number of pages/bytes we need for compressed data (worst case). */
371#define LZO_CMP_PAGES DIV_ROUND_UP(lzo1x_worst_compress(LZO_UNC_SIZE) + \
372 LZO_HEADER, PAGE_SIZE)
373#define LZO_CMP_SIZE (LZO_CMP_PAGES * PAGE_SIZE)
374
360/** 375/**
361 * save_image - save the suspend image data 376 * save_image - save the suspend image data
362 */ 377 */
@@ -404,6 +419,137 @@ static int save_image(struct swap_map_handle *handle,
404 return ret; 419 return ret;
405} 420}
406 421
422
423/**
424 * save_image_lzo - Save the suspend image data compressed with LZO.
425 * @handle: Swap mam handle to use for saving the image.
426 * @snapshot: Image to read data from.
427 * @nr_to_write: Number of pages to save.
428 */
429static int save_image_lzo(struct swap_map_handle *handle,
430 struct snapshot_handle *snapshot,
431 unsigned int nr_to_write)
432{
433 unsigned int m;
434 int ret = 0;
435 int nr_pages;
436 int err2;
437 struct bio *bio;
438 struct timeval start;
439 struct timeval stop;
440 size_t off, unc_len, cmp_len;
441 unsigned char *unc, *cmp, *wrk, *page;
442
443 page = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
444 if (!page) {
445 printk(KERN_ERR "PM: Failed to allocate LZO page\n");
446 return -ENOMEM;
447 }
448
449 wrk = vmalloc(LZO1X_1_MEM_COMPRESS);
450 if (!wrk) {
451 printk(KERN_ERR "PM: Failed to allocate LZO workspace\n");
452 free_page((unsigned long)page);
453 return -ENOMEM;
454 }
455
456 unc = vmalloc(LZO_UNC_SIZE);
457 if (!unc) {
458 printk(KERN_ERR "PM: Failed to allocate LZO uncompressed\n");
459 vfree(wrk);
460 free_page((unsigned long)page);
461 return -ENOMEM;
462 }
463
464 cmp = vmalloc(LZO_CMP_SIZE);
465 if (!cmp) {
466 printk(KERN_ERR "PM: Failed to allocate LZO compressed\n");
467 vfree(unc);
468 vfree(wrk);
469 free_page((unsigned long)page);
470 return -ENOMEM;
471 }
472
473 printk(KERN_INFO
474 "PM: Compressing and saving image data (%u pages) ... ",
475 nr_to_write);
476 m = nr_to_write / 100;
477 if (!m)
478 m = 1;
479 nr_pages = 0;
480 bio = NULL;
481 do_gettimeofday(&start);
482 for (;;) {
483 for (off = 0; off < LZO_UNC_SIZE; off += PAGE_SIZE) {
484 ret = snapshot_read_next(snapshot);
485 if (ret < 0)
486 goto out_finish;
487
488 if (!ret)
489 break;
490
491 memcpy(unc + off, data_of(*snapshot), PAGE_SIZE);
492
493 if (!(nr_pages % m))
494 printk(KERN_CONT "\b\b\b\b%3d%%", nr_pages / m);
495 nr_pages++;
496 }
497
498 if (!off)
499 break;
500
501 unc_len = off;
502 ret = lzo1x_1_compress(unc, unc_len,
503 cmp + LZO_HEADER, &cmp_len, wrk);
504 if (ret < 0) {
505 printk(KERN_ERR "PM: LZO compression failed\n");
506 break;
507 }
508
509 if (unlikely(!cmp_len ||
510 cmp_len > lzo1x_worst_compress(unc_len))) {
511 printk(KERN_ERR "PM: Invalid LZO compressed length\n");
512 ret = -1;
513 break;
514 }
515
516 *(size_t *)cmp = cmp_len;
517
518 /*
519 * Given we are writing one page at a time to disk, we copy
520 * that much from the buffer, although the last bit will likely
521 * be smaller than full page. This is OK - we saved the length
522 * of the compressed data, so any garbage at the end will be
523 * discarded when we read it.
524 */
525 for (off = 0; off < LZO_HEADER + cmp_len; off += PAGE_SIZE) {
526 memcpy(page, cmp + off, PAGE_SIZE);
527
528 ret = swap_write_page(handle, page, &bio);
529 if (ret)
530 goto out_finish;
531 }
532 }
533
534out_finish:
535 err2 = hib_wait_on_bio_chain(&bio);
536 do_gettimeofday(&stop);
537 if (!ret)
538 ret = err2;
539 if (!ret)
540 printk(KERN_CONT "\b\b\b\bdone\n");
541 else
542 printk(KERN_CONT "\n");
543 swsusp_show_speed(&start, &stop, nr_to_write, "Wrote");
544
545 vfree(cmp);
546 vfree(unc);
547 vfree(wrk);
548 free_page((unsigned long)page);
549
550 return ret;
551}
552
407/** 553/**
408 * enough_swap - Make sure we have enough swap to save the image. 554 * enough_swap - Make sure we have enough swap to save the image.
409 * 555 *
@@ -411,12 +557,16 @@ static int save_image(struct swap_map_handle *handle,
411 * space avaiable from the resume partition. 557 * space avaiable from the resume partition.
412 */ 558 */
413 559
414static int enough_swap(unsigned int nr_pages) 560static int enough_swap(unsigned int nr_pages, unsigned int flags)
415{ 561{
416 unsigned int free_swap = count_swap_pages(root_swap, 1); 562 unsigned int free_swap = count_swap_pages(root_swap, 1);
563 unsigned int required;
417 564
418 pr_debug("PM: Free swap pages: %u\n", free_swap); 565 pr_debug("PM: Free swap pages: %u\n", free_swap);
419 return free_swap > nr_pages + PAGES_FOR_IO; 566
567 required = PAGES_FOR_IO + ((flags & SF_NOCOMPRESS_MODE) ?
568 nr_pages : (nr_pages * LZO_CMP_PAGES) / LZO_UNC_PAGES + 1);
569 return free_swap > required;
420} 570}
421 571
422/** 572/**
@@ -443,7 +593,7 @@ int swsusp_write(unsigned int flags)
443 printk(KERN_ERR "PM: Cannot get swap writer\n"); 593 printk(KERN_ERR "PM: Cannot get swap writer\n");
444 return error; 594 return error;
445 } 595 }
446 if (!enough_swap(pages)) { 596 if (!enough_swap(pages, flags)) {
447 printk(KERN_ERR "PM: Not enough free swap\n"); 597 printk(KERN_ERR "PM: Not enough free swap\n");
448 error = -ENOSPC; 598 error = -ENOSPC;
449 goto out_finish; 599 goto out_finish;
@@ -458,8 +608,11 @@ int swsusp_write(unsigned int flags)
458 } 608 }
459 header = (struct swsusp_info *)data_of(snapshot); 609 header = (struct swsusp_info *)data_of(snapshot);
460 error = swap_write_page(&handle, header, NULL); 610 error = swap_write_page(&handle, header, NULL);
461 if (!error) 611 if (!error) {
462 error = save_image(&handle, &snapshot, pages - 1); 612 error = (flags & SF_NOCOMPRESS_MODE) ?
613 save_image(&handle, &snapshot, pages - 1) :
614 save_image_lzo(&handle, &snapshot, pages - 1);
615 }
463out_finish: 616out_finish:
464 error = swap_writer_finish(&handle, flags, error); 617 error = swap_writer_finish(&handle, flags, error);
465 return error; 618 return error;
@@ -590,9 +743,152 @@ static int load_image(struct swap_map_handle *handle,
590} 743}
591 744
592/** 745/**
746 * load_image_lzo - Load compressed image data and decompress them with LZO.
747 * @handle: Swap map handle to use for loading data.
748 * @snapshot: Image to copy uncompressed data into.
749 * @nr_to_read: Number of pages to load.
750 */
751static int load_image_lzo(struct swap_map_handle *handle,
752 struct snapshot_handle *snapshot,
753 unsigned int nr_to_read)
754{
755 unsigned int m;
756 int error = 0;
757 struct bio *bio;
758 struct timeval start;
759 struct timeval stop;
760 unsigned nr_pages;
761 size_t i, off, unc_len, cmp_len;
762 unsigned char *unc, *cmp, *page[LZO_CMP_PAGES];
763
764 for (i = 0; i < LZO_CMP_PAGES; i++) {
765 page[i] = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
766 if (!page[i]) {
767 printk(KERN_ERR "PM: Failed to allocate LZO page\n");
768
769 while (i)
770 free_page((unsigned long)page[--i]);
771
772 return -ENOMEM;
773 }
774 }
775
776 unc = vmalloc(LZO_UNC_SIZE);
777 if (!unc) {
778 printk(KERN_ERR "PM: Failed to allocate LZO uncompressed\n");
779
780 for (i = 0; i < LZO_CMP_PAGES; i++)
781 free_page((unsigned long)page[i]);
782
783 return -ENOMEM;
784 }
785
786 cmp = vmalloc(LZO_CMP_SIZE);
787 if (!cmp) {
788 printk(KERN_ERR "PM: Failed to allocate LZO compressed\n");
789
790 vfree(unc);
791 for (i = 0; i < LZO_CMP_PAGES; i++)
792 free_page((unsigned long)page[i]);
793
794 return -ENOMEM;
795 }
796
797 printk(KERN_INFO
798 "PM: Loading and decompressing image data (%u pages) ... ",
799 nr_to_read);
800 m = nr_to_read / 100;
801 if (!m)
802 m = 1;
803 nr_pages = 0;
804 bio = NULL;
805 do_gettimeofday(&start);
806
807 error = snapshot_write_next(snapshot);
808 if (error <= 0)
809 goto out_finish;
810
811 for (;;) {
812 error = swap_read_page(handle, page[0], NULL); /* sync */
813 if (error)
814 break;
815
816 cmp_len = *(size_t *)page[0];
817 if (unlikely(!cmp_len ||
818 cmp_len > lzo1x_worst_compress(LZO_UNC_SIZE))) {
819 printk(KERN_ERR "PM: Invalid LZO compressed length\n");
820 error = -1;
821 break;
822 }
823
824 for (off = PAGE_SIZE, i = 1;
825 off < LZO_HEADER + cmp_len; off += PAGE_SIZE, i++) {
826 error = swap_read_page(handle, page[i], &bio);
827 if (error)
828 goto out_finish;
829 }
830
831 error = hib_wait_on_bio_chain(&bio); /* need all data now */
832 if (error)
833 goto out_finish;
834
835 for (off = 0, i = 0;
836 off < LZO_HEADER + cmp_len; off += PAGE_SIZE, i++) {
837 memcpy(cmp + off, page[i], PAGE_SIZE);
838 }
839
840 unc_len = LZO_UNC_SIZE;
841 error = lzo1x_decompress_safe(cmp + LZO_HEADER, cmp_len,
842 unc, &unc_len);
843 if (error < 0) {
844 printk(KERN_ERR "PM: LZO decompression failed\n");
845 break;
846 }
847
848 if (unlikely(!unc_len ||
849 unc_len > LZO_UNC_SIZE ||
850 unc_len & (PAGE_SIZE - 1))) {
851 printk(KERN_ERR "PM: Invalid LZO uncompressed length\n");
852 error = -1;
853 break;
854 }
855
856 for (off = 0; off < unc_len; off += PAGE_SIZE) {
857 memcpy(data_of(*snapshot), unc + off, PAGE_SIZE);
858
859 if (!(nr_pages % m))
860 printk("\b\b\b\b%3d%%", nr_pages / m);
861 nr_pages++;
862
863 error = snapshot_write_next(snapshot);
864 if (error <= 0)
865 goto out_finish;
866 }
867 }
868
869out_finish:
870 do_gettimeofday(&stop);
871 if (!error) {
872 printk("\b\b\b\bdone\n");
873 snapshot_write_finalize(snapshot);
874 if (!snapshot_image_loaded(snapshot))
875 error = -ENODATA;
876 } else
877 printk("\n");
878 swsusp_show_speed(&start, &stop, nr_to_read, "Read");
879
880 vfree(cmp);
881 vfree(unc);
882 for (i = 0; i < LZO_CMP_PAGES; i++)
883 free_page((unsigned long)page[i]);
884
885 return error;
886}
887
888/**
593 * swsusp_read - read the hibernation image. 889 * swsusp_read - read the hibernation image.
594 * @flags_p: flags passed by the "frozen" kernel in the image header should 890 * @flags_p: flags passed by the "frozen" kernel in the image header should
595 * be written into this memeory location 891 * be written into this memory location
596 */ 892 */
597 893
598int swsusp_read(unsigned int *flags_p) 894int swsusp_read(unsigned int *flags_p)
@@ -612,8 +908,11 @@ int swsusp_read(unsigned int *flags_p)
612 goto end; 908 goto end;
613 if (!error) 909 if (!error)
614 error = swap_read_page(&handle, header, NULL); 910 error = swap_read_page(&handle, header, NULL);
615 if (!error) 911 if (!error) {
616 error = load_image(&handle, &snapshot, header->pages - 1); 912 error = (*flags_p & SF_NOCOMPRESS_MODE) ?
913 load_image(&handle, &snapshot, header->pages - 1) :
914 load_image_lzo(&handle, &snapshot, header->pages - 1);
915 }
617 swap_reader_finish(&handle); 916 swap_reader_finish(&handle);
618end: 917end:
619 if (!error) 918 if (!error)
@@ -631,16 +930,17 @@ int swsusp_check(void)
631{ 930{
632 int error; 931 int error;
633 932
634 hib_resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); 933 hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device,
934 FMODE_READ, NULL);
635 if (!IS_ERR(hib_resume_bdev)) { 935 if (!IS_ERR(hib_resume_bdev)) {
636 set_blocksize(hib_resume_bdev, PAGE_SIZE); 936 set_blocksize(hib_resume_bdev, PAGE_SIZE);
637 memset(swsusp_header, 0, PAGE_SIZE); 937 clear_page(swsusp_header);
638 error = hib_bio_read_page(swsusp_resume_block, 938 error = hib_bio_read_page(swsusp_resume_block,
639 swsusp_header, NULL); 939 swsusp_header, NULL);
640 if (error) 940 if (error)
641 goto put; 941 goto put;
642 942
643 if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) { 943 if (!memcmp(HIBERNATE_SIG, swsusp_header->sig, 10)) {
644 memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); 944 memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10);
645 /* Reset swap signature now */ 945 /* Reset swap signature now */
646 error = hib_bio_write_page(swsusp_resume_block, 946 error = hib_bio_write_page(swsusp_resume_block,
@@ -653,13 +953,13 @@ put:
653 if (error) 953 if (error)
654 blkdev_put(hib_resume_bdev, FMODE_READ); 954 blkdev_put(hib_resume_bdev, FMODE_READ);
655 else 955 else
656 pr_debug("PM: Signature found, resuming\n"); 956 pr_debug("PM: Image signature found, resuming\n");
657 } else { 957 } else {
658 error = PTR_ERR(hib_resume_bdev); 958 error = PTR_ERR(hib_resume_bdev);
659 } 959 }
660 960
661 if (error) 961 if (error)
662 pr_debug("PM: Error %d checking image file\n", error); 962 pr_debug("PM: Image not found (code %d)\n", error);
663 963
664 return error; 964 return error;
665} 965}