swap.c (5e2aa2ed08e2e280121dc7cf5609c87d464f12ef) | swap.c (db597605821fccc49876705aea5db5443d67e53e) |
---|---|
1/* 2 * linux/kernel/power/swap.c 3 * 4 * This file provides functions for reading the suspend image from 5 * and writing it to a swap partition. 6 * 7 * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz> 8 * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> --- 16 unchanged lines hidden (view full) --- 25#include <linux/pm.h> 26#include <linux/slab.h> 27#include <linux/lzo.h> 28#include <linux/vmalloc.h> 29#include <linux/cpumask.h> 30#include <linux/atomic.h> 31#include <linux/kthread.h> 32#include <linux/crc32.h> | 1/* 2 * linux/kernel/power/swap.c 3 * 4 * This file provides functions for reading the suspend image from 5 * and writing it to a swap partition. 6 * 7 * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz> 8 * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> --- 16 unchanged lines hidden (view full) --- 25#include <linux/pm.h> 26#include <linux/slab.h> 27#include <linux/lzo.h> 28#include <linux/vmalloc.h> 29#include <linux/cpumask.h> 30#include <linux/atomic.h> 31#include <linux/kthread.h> 32#include <linux/crc32.h> |
33#include <linux/ktime.h> |
|
33 34#include "power.h" 35 36#define HIBERNATE_SIG "S1SUSPEND" 37 38/* 39 * The swap map is a data structure used for keeping track of each page 40 * written to a swap partition. It consists of many swap_map_page --- 399 unchanged lines hidden (view full) --- 440 struct snapshot_handle *snapshot, 441 unsigned int nr_to_write) 442{ 443 unsigned int m; 444 int ret; 445 int nr_pages; 446 int err2; 447 struct bio *bio; | 34 35#include "power.h" 36 37#define HIBERNATE_SIG "S1SUSPEND" 38 39/* 40 * The swap map is a data structure used for keeping track of each page 41 * written to a swap partition. It consists of many swap_map_page --- 399 unchanged lines hidden (view full) --- 441 struct snapshot_handle *snapshot, 442 unsigned int nr_to_write) 443{ 444 unsigned int m; 445 int ret; 446 int nr_pages; 447 int err2; 448 struct bio *bio; |
448 struct timeval start; 449 struct timeval stop; | 449 ktime_t start; 450 ktime_t stop; |
450 451 printk(KERN_INFO "PM: Saving image data pages (%u pages)...\n", 452 nr_to_write); 453 m = nr_to_write / 10; 454 if (!m) 455 m = 1; 456 nr_pages = 0; 457 bio = NULL; | 451 452 printk(KERN_INFO "PM: Saving image data pages (%u pages)...\n", 453 nr_to_write); 454 m = nr_to_write / 10; 455 if (!m) 456 m = 1; 457 nr_pages = 0; 458 bio = NULL; |
458 do_gettimeofday(&start); | 459 start = ktime_get(); |
459 while (1) { 460 ret = snapshot_read_next(snapshot); 461 if (ret <= 0) 462 break; 463 ret = swap_write_page(handle, data_of(*snapshot), &bio); 464 if (ret) 465 break; 466 if (!(nr_pages % m)) 467 printk(KERN_INFO "PM: Image saving progress: %3d%%\n", 468 nr_pages / m * 10); 469 nr_pages++; 470 } 471 err2 = hib_wait_on_bio_chain(&bio); | 460 while (1) { 461 ret = snapshot_read_next(snapshot); 462 if (ret <= 0) 463 break; 464 ret = swap_write_page(handle, data_of(*snapshot), &bio); 465 if (ret) 466 break; 467 if (!(nr_pages % m)) 468 printk(KERN_INFO "PM: Image saving progress: %3d%%\n", 469 nr_pages / m * 10); 470 nr_pages++; 471 } 472 err2 = hib_wait_on_bio_chain(&bio); |
472 do_gettimeofday(&stop); | 473 stop = ktime_get(); |
473 if (!ret) 474 ret = err2; 475 if (!ret) 476 printk(KERN_INFO "PM: Image saving done.\n"); | 474 if (!ret) 475 ret = err2; 476 if (!ret) 477 printk(KERN_INFO "PM: Image saving done.\n"); |
477 swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); | 478 swsusp_show_speed(start, stop, nr_to_write, "Wrote"); |
478 return ret; 479} 480 481/** 482 * Structure used for CRC32. 483 */ 484struct crc_data { 485 struct task_struct *thr; /* thread */ --- 89 unchanged lines hidden (view full) --- 575 struct snapshot_handle *snapshot, 576 unsigned int nr_to_write) 577{ 578 unsigned int m; 579 int ret = 0; 580 int nr_pages; 581 int err2; 582 struct bio *bio; | 479 return ret; 480} 481 482/** 483 * Structure used for CRC32. 484 */ 485struct crc_data { 486 struct task_struct *thr; /* thread */ --- 89 unchanged lines hidden (view full) --- 576 struct snapshot_handle *snapshot, 577 unsigned int nr_to_write) 578{ 579 unsigned int m; 580 int ret = 0; 581 int nr_pages; 582 int err2; 583 struct bio *bio; |
583 struct timeval start; 584 struct timeval stop; | 584 ktime_t start; 585 ktime_t stop; |
585 size_t off; 586 unsigned thr, run_threads, nr_threads; 587 unsigned char *page = NULL; 588 struct cmp_data *data = NULL; 589 struct crc_data *crc = NULL; 590 591 /* 592 * We'll limit the number of threads for compression to limit memory --- 76 unchanged lines hidden (view full) --- 669 "PM: Using %u thread(s) for compression.\n" 670 "PM: Compressing and saving image data (%u pages)...\n", 671 nr_threads, nr_to_write); 672 m = nr_to_write / 10; 673 if (!m) 674 m = 1; 675 nr_pages = 0; 676 bio = NULL; | 586 size_t off; 587 unsigned thr, run_threads, nr_threads; 588 unsigned char *page = NULL; 589 struct cmp_data *data = NULL; 590 struct crc_data *crc = NULL; 591 592 /* 593 * We'll limit the number of threads for compression to limit memory --- 76 unchanged lines hidden (view full) --- 670 "PM: Using %u thread(s) for compression.\n" 671 "PM: Compressing and saving image data (%u pages)...\n", 672 nr_threads, nr_to_write); 673 m = nr_to_write / 10; 674 if (!m) 675 m = 1; 676 nr_pages = 0; 677 bio = NULL; |
677 do_gettimeofday(&start); | 678 start = ktime_get(); |
678 for (;;) { 679 for (thr = 0; thr < nr_threads; thr++) { 680 for (off = 0; off < LZO_UNC_SIZE; off += PAGE_SIZE) { 681 ret = snapshot_read_next(snapshot); 682 if (ret < 0) 683 goto out_finish; 684 685 if (!ret) --- 68 unchanged lines hidden (view full) --- 754 } 755 756 wait_event(crc->done, atomic_read(&crc->stop)); 757 atomic_set(&crc->stop, 0); 758 } 759 760out_finish: 761 err2 = hib_wait_on_bio_chain(&bio); | 679 for (;;) { 680 for (thr = 0; thr < nr_threads; thr++) { 681 for (off = 0; off < LZO_UNC_SIZE; off += PAGE_SIZE) { 682 ret = snapshot_read_next(snapshot); 683 if (ret < 0) 684 goto out_finish; 685 686 if (!ret) --- 68 unchanged lines hidden (view full) --- 755 } 756 757 wait_event(crc->done, atomic_read(&crc->stop)); 758 atomic_set(&crc->stop, 0); 759 } 760 761out_finish: 762 err2 = hib_wait_on_bio_chain(&bio); |
762 do_gettimeofday(&stop); | 763 stop = ktime_get(); |
763 if (!ret) 764 ret = err2; 765 if (!ret) 766 printk(KERN_INFO "PM: Image saving done.\n"); | 764 if (!ret) 765 ret = err2; 766 if (!ret) 767 printk(KERN_INFO "PM: Image saving done.\n"); |
767 swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); | 768 swsusp_show_speed(start, stop, nr_to_write, "Wrote"); |
768out_clean: 769 if (crc) { 770 if (crc->thr) 771 kthread_stop(crc->thr); 772 kfree(crc); 773 } 774 if (data) { 775 for (thr = 0; thr < nr_threads; thr++) --- 184 unchanged lines hidden (view full) --- 960 */ 961 962static int load_image(struct swap_map_handle *handle, 963 struct snapshot_handle *snapshot, 964 unsigned int nr_to_read) 965{ 966 unsigned int m; 967 int ret = 0; | 769out_clean: 770 if (crc) { 771 if (crc->thr) 772 kthread_stop(crc->thr); 773 kfree(crc); 774 } 775 if (data) { 776 for (thr = 0; thr < nr_threads; thr++) --- 184 unchanged lines hidden (view full) --- 961 */ 962 963static int load_image(struct swap_map_handle *handle, 964 struct snapshot_handle *snapshot, 965 unsigned int nr_to_read) 966{ 967 unsigned int m; 968 int ret = 0; |
968 struct timeval start; 969 struct timeval stop; | 969 ktime_t start; 970 ktime_t stop; |
970 struct bio *bio; 971 int err2; 972 unsigned nr_pages; 973 974 printk(KERN_INFO "PM: Loading image data pages (%u pages)...\n", 975 nr_to_read); 976 m = nr_to_read / 10; 977 if (!m) 978 m = 1; 979 nr_pages = 0; 980 bio = NULL; | 971 struct bio *bio; 972 int err2; 973 unsigned nr_pages; 974 975 printk(KERN_INFO "PM: Loading image data pages (%u pages)...\n", 976 nr_to_read); 977 m = nr_to_read / 10; 978 if (!m) 979 m = 1; 980 nr_pages = 0; 981 bio = NULL; |
981 do_gettimeofday(&start); | 982 start = ktime_get(); |
982 for ( ; ; ) { 983 ret = snapshot_write_next(snapshot); 984 if (ret <= 0) 985 break; 986 ret = swap_read_page(handle, data_of(*snapshot), &bio); 987 if (ret) 988 break; 989 if (snapshot->sync_read) 990 ret = hib_wait_on_bio_chain(&bio); 991 if (ret) 992 break; 993 if (!(nr_pages % m)) 994 printk(KERN_INFO "PM: Image loading progress: %3d%%\n", 995 nr_pages / m * 10); 996 nr_pages++; 997 } 998 err2 = hib_wait_on_bio_chain(&bio); | 983 for ( ; ; ) { 984 ret = snapshot_write_next(snapshot); 985 if (ret <= 0) 986 break; 987 ret = swap_read_page(handle, data_of(*snapshot), &bio); 988 if (ret) 989 break; 990 if (snapshot->sync_read) 991 ret = hib_wait_on_bio_chain(&bio); 992 if (ret) 993 break; 994 if (!(nr_pages % m)) 995 printk(KERN_INFO "PM: Image loading progress: %3d%%\n", 996 nr_pages / m * 10); 997 nr_pages++; 998 } 999 err2 = hib_wait_on_bio_chain(&bio); |
999 do_gettimeofday(&stop); | 1000 stop = ktime_get(); |
1000 if (!ret) 1001 ret = err2; 1002 if (!ret) { 1003 printk(KERN_INFO "PM: Image loading done.\n"); 1004 snapshot_write_finalize(snapshot); 1005 if (!snapshot_image_loaded(snapshot)) 1006 ret = -ENODATA; 1007 } | 1001 if (!ret) 1002 ret = err2; 1003 if (!ret) { 1004 printk(KERN_INFO "PM: Image loading done.\n"); 1005 snapshot_write_finalize(snapshot); 1006 if (!snapshot_image_loaded(snapshot)) 1007 ret = -ENODATA; 1008 } |
1008 swsusp_show_speed(&start, &stop, nr_to_read, "Read"); | 1009 swsusp_show_speed(start, stop, nr_to_read, "Read"); |
1009 return ret; 1010} 1011 1012/** 1013 * Structure used for LZO data decompression. 1014 */ 1015struct dec_data { 1016 struct task_struct *thr; /* thread */ --- 45 unchanged lines hidden (view full) --- 1062static int load_image_lzo(struct swap_map_handle *handle, 1063 struct snapshot_handle *snapshot, 1064 unsigned int nr_to_read) 1065{ 1066 unsigned int m; 1067 int ret = 0; 1068 int eof = 0; 1069 struct bio *bio; | 1010 return ret; 1011} 1012 1013/** 1014 * Structure used for LZO data decompression. 1015 */ 1016struct dec_data { 1017 struct task_struct *thr; /* thread */ --- 45 unchanged lines hidden (view full) --- 1063static int load_image_lzo(struct swap_map_handle *handle, 1064 struct snapshot_handle *snapshot, 1065 unsigned int nr_to_read) 1066{ 1067 unsigned int m; 1068 int ret = 0; 1069 int eof = 0; 1070 struct bio *bio; |
1070 struct timeval start; 1071 struct timeval stop; | 1071 ktime_t start; 1072 ktime_t stop; |
1072 unsigned nr_pages; 1073 size_t off; 1074 unsigned i, thr, run_threads, nr_threads; 1075 unsigned ring = 0, pg = 0, ring_size = 0, 1076 have = 0, want, need, asked = 0; 1077 unsigned long read_pages = 0; 1078 unsigned char **page = NULL; 1079 struct dec_data *data = NULL; --- 105 unchanged lines hidden (view full) --- 1185 "PM: Using %u thread(s) for decompression.\n" 1186 "PM: Loading and decompressing image data (%u pages)...\n", 1187 nr_threads, nr_to_read); 1188 m = nr_to_read / 10; 1189 if (!m) 1190 m = 1; 1191 nr_pages = 0; 1192 bio = NULL; | 1073 unsigned nr_pages; 1074 size_t off; 1075 unsigned i, thr, run_threads, nr_threads; 1076 unsigned ring = 0, pg = 0, ring_size = 0, 1077 have = 0, want, need, asked = 0; 1078 unsigned long read_pages = 0; 1079 unsigned char **page = NULL; 1080 struct dec_data *data = NULL; --- 105 unchanged lines hidden (view full) --- 1186 "PM: Using %u thread(s) for decompression.\n" 1187 "PM: Loading and decompressing image data (%u pages)...\n", 1188 nr_threads, nr_to_read); 1189 m = nr_to_read / 10; 1190 if (!m) 1191 m = 1; 1192 nr_pages = 0; 1193 bio = NULL; |
1193 do_gettimeofday(&start); | 1194 start = ktime_get(); |
1194 1195 ret = snapshot_write_next(snapshot); 1196 if (ret <= 0) 1197 goto out_finish; 1198 1199 for(;;) { 1200 for (i = 0; !eof && i < want; i++) { 1201 ret = swap_read_page(handle, page[ring], &bio); --- 136 unchanged lines hidden (view full) --- 1338 wake_up(&crc->go); 1339 } 1340 1341out_finish: 1342 if (crc->run_threads) { 1343 wait_event(crc->done, atomic_read(&crc->stop)); 1344 atomic_set(&crc->stop, 0); 1345 } | 1195 1196 ret = snapshot_write_next(snapshot); 1197 if (ret <= 0) 1198 goto out_finish; 1199 1200 for(;;) { 1201 for (i = 0; !eof && i < want; i++) { 1202 ret = swap_read_page(handle, page[ring], &bio); --- 136 unchanged lines hidden (view full) --- 1339 wake_up(&crc->go); 1340 } 1341 1342out_finish: 1343 if (crc->run_threads) { 1344 wait_event(crc->done, atomic_read(&crc->stop)); 1345 atomic_set(&crc->stop, 0); 1346 } |
1346 do_gettimeofday(&stop); | 1347 stop = ktime_get(); |
1347 if (!ret) { 1348 printk(KERN_INFO "PM: Image loading done.\n"); 1349 snapshot_write_finalize(snapshot); 1350 if (!snapshot_image_loaded(snapshot)) 1351 ret = -ENODATA; 1352 if (!ret) { 1353 if (swsusp_header->flags & SF_CRC32_MODE) { 1354 if(handle->crc32 != swsusp_header->crc32) { 1355 printk(KERN_ERR 1356 "PM: Invalid image CRC32!\n"); 1357 ret = -ENODATA; 1358 } 1359 } 1360 } 1361 } | 1348 if (!ret) { 1349 printk(KERN_INFO "PM: Image loading done.\n"); 1350 snapshot_write_finalize(snapshot); 1351 if (!snapshot_image_loaded(snapshot)) 1352 ret = -ENODATA; 1353 if (!ret) { 1354 if (swsusp_header->flags & SF_CRC32_MODE) { 1355 if(handle->crc32 != swsusp_header->crc32) { 1356 printk(KERN_ERR 1357 "PM: Invalid image CRC32!\n"); 1358 ret = -ENODATA; 1359 } 1360 } 1361 } 1362 } |
1362 swsusp_show_speed(&start, &stop, nr_to_read, "Read"); | 1363 swsusp_show_speed(start, stop, nr_to_read, "Read"); |
1363out_clean: 1364 for (i = 0; i < ring_size; i++) 1365 free_page((unsigned long)page[i]); 1366 if (crc) { 1367 if (crc->thr) 1368 kthread_stop(crc->thr); 1369 kfree(crc); 1370 } --- 141 unchanged lines hidden --- | 1364out_clean: 1365 for (i = 0; i < ring_size; i++) 1366 free_page((unsigned long)page[i]); 1367 if (crc) { 1368 if (crc->thr) 1369 kthread_stop(crc->thr); 1370 kfree(crc); 1371 } --- 141 unchanged lines hidden --- |