Author: lmasko Date: Sat Apr 4 13:01:36 2009 GMT Module: SOURCES Tag: HEAD ---- Log message: - TuxOnIce up to stable version 3.0.
---- Files affected: SOURCES: kernel-tuxonice.patch (1.2 -> 1.3) ---- Diffs: ================================================================ Index: SOURCES/kernel-tuxonice.patch diff -u SOURCES/kernel-tuxonice.patch:1.2 SOURCES/kernel-tuxonice.patch:1.3 --- SOURCES/kernel-tuxonice.patch:1.2 Tue Mar 31 14:04:40 2009 +++ SOURCES/kernel-tuxonice.patch Sat Apr 4 15:01:30 2009 @@ -1,11 +1,11 @@ diff --git a/Documentation/power/tuxonice-internals.txt b/Documentation/power/tuxonice-internals.txt new file mode 100644 -index 0000000..cca629a +index 0000000..7a96186 --- /dev/null +++ b/Documentation/power/tuxonice-internals.txt -@@ -0,0 +1,474 @@ +@@ -0,0 +1,477 @@ + TuxOnIce 3.0 Internal Documentation. -+ Updated to 11 March 2008 ++ Updated to 26 March 2009 + +1. Introduction. + @@ -146,12 +146,15 @@ + circumvented by dividing the memory to be saved into two parts, called + pagesets. + -+ Pageset2 contains the page cache - the pages on the active and inactive -+ lists. These pages aren't needed or modifed while TuxOnIce is running, so -+ they can be safely written without an atomic copy. They are therefore -+ saved first and reloaded last. While saving these pages, TuxOnIce carefully -+ ensures that the work of writing the pages doesn't make the image -+ inconsistent. ++ Pageset2 contains most of the page cache - the pages on the active and ++ inactive LRU lists that aren't needed or modified while TuxOnIce is ++ running, so they can be safely written without an atomic copy. They are ++ therefore saved first and reloaded last. While saving these pages, ++ TuxOnIce carefully ensures that the work of writing the pages doesn't make ++ the image inconsistent. With the support for Kernel (Video) Mode Setting ++ going into the kernel at the time of writing, we need to check for pages ++ on the LRU that are used by KMS, and exclude them from pageset2. They are ++ atomically copied as part of pageset 1. + + Once pageset2 has been saved, we prepare to do the atomic copy of remaining + memory. As part of the preparation, we power down drivers, thereby providing @@ -164,7 +167,11 @@ + 'extra_pages_allowance', which is used to seek to ensure sufficient memory + is available for drivers at this point. TuxOnIce also lets the user set this + value to 0. In this case, a test driver suspend is done while preparing the -+ image, and the difference (plus a margin) used instead. ++ image, and the difference (plus a margin) used instead. TuxOnIce will also ++ automatically restart the hibernation process (twice at most) if it finds ++ that the extra pages allowance is not sufficient. It will then use what was ++ actually needed (plus a margin, again). Failure to hibernate should thus ++ be an extremely rare occurence. + + Having suspended the drivers, we save the CPU context before making an + atomic copy of pageset1, resuming the drivers and saving the atomic copy. @@ -183,7 +190,7 @@ + and then a sync occurs, the filesystem will be corrupted - at least until + resume time and another sync of the restored data. Since there is a + possibility that the user might not resume or (may it never be!) that -+ suspend might oops, we do our utmost to avoid syncing filesystems after ++ TuxOnIce might oops, we do our utmost to avoid syncing filesystems after + copying pageset1. + + e. Power down. @@ -205,10 +212,8 @@ + + TuxOnIce records which pages will be in pageset1, pageset2, the destination + of the atomic copy and the source of the atomically restored image using -+ bitmaps. These bitmaps are created from order zero allocations to maximise -+ reliability. The individual pages are combined together with pointers to -+ form per-zone bitmaps, which are in turn combined with another layer of -+ pointers to construct the overall bitmap. ++ bitmaps. The code used is that written for swsusp, with small improvements ++ to match TuxOnIce's requirements. + + The pageset1 bitmap is thus easily stored in the image header for use at + resume time. @@ -229,13 +234,12 @@ + the n+1th page, given the location of the nth page. Bitwise optimisations + help here. + -+ The data structure is: unsigned long ***. -+ + b) Extents for block data. + + TuxOnIce supports writing the image to multiple block devices. In the case + of swap, multiple partitions and/or files may be in use, and we happily use -+ them all. This is accomplished as follows: ++ them all (with the exception of compcache pages, which we allocate but do ++ not use). This use of multiple block devices is accomplished as follows: + + Whatever the actual source of the allocated storage, the destination of the + image can be viewed in terms of one or more block devices, and on each @@ -288,8 +292,8 @@ + utilises LVM for storage, as they will need to dmsetup their partitions in + such a way as to maintain this consistency at resume time. + -+ bmap_shift and blocks_per_page record apply the effects of variations in -+ blocks per page settings for the filesystem and underlying bdev. For most ++ bmap_shift and blocks_per_page apply the effects of variations in blocks ++ per page settings for the filesystem and underlying bdev. For most + filesystems, these are the same, but for xfs, they can have independant + values. + @@ -401,8 +405,7 @@ + During the writing of an image, the core code feeds pages one at a time + to the first module. This module performs whatever transformations it + implements on the incoming data, completely consuming the incoming data and -+ feeding output in a similar manner to the next module. A module may buffer -+ its output. ++ feeding output in a similar manner to the next module. + + All routines are SMP safe, and the final result of the transformations is + written with an index (provided by the core) and size of the output by the @@ -453,23 +456,23 @@ + + This brings us naturally to support for configuring TuxOnIce. We desired to + provide a way to make TuxOnIce as flexible and configurable as possible. -+ The user shouldn't have to reboot just because they want to now suspend to ++ The user shouldn't have to reboot just because they want to now hibernate to + a file instead of a partition, for example. + + To accomplish this, TuxOnIce implements a very generic means whereby the + core and modules can register new sysfs entries. All TuxOnIce entries use -+ a single _store and _show routine, both of which are found in sysfs.c in -+ the kernel/power directory. These routines handle the most common operations -+ - getting and setting the values of bits, integers, longs, unsigned longs -+ and strings in one place, and allow overrides for customised get and set -+ options as well as side-effect routines for all reads and writes. ++ a single _store and _show routine, both of which are found in ++ tuxonice_sysfs.c in the kernel/power directory. These routines handle the ++ most common operations - getting and setting the values of bits, integers, ++ longs, unsigned longs and strings in one place, and allow overrides for ++ customised get and set options as well as side-effect routines for all ++ reads and writes. + + When combined with some simple macros, a new sysfs entry can then be defined + in just a couple of lines: + -+ { TOI_ATTR("progress_granularity", SYSFS_RW), -+ SYSFS_INT(&progress_granularity, 1, 2048) -+ }, ++ SYSFS_INT("progress_granularity", SYSFS_RW, &progress_granularity, 1, ++ 2048, 0, NULL), + + This defines a sysfs entry named "progress_granularity" which is rw and + allows the user to access an integer stored at &progress_granularity, giving @@ -1235,17 +1238,17 @@ + testing. His efforts have contributed as much to TuxOnIce as any of the + names above. diff --git a/MAINTAINERS b/MAINTAINERS -index 61aeb5a..4132787 100644 +index 5d460c9..a39a4fb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -4336,6 +4336,13 @@ P: Maciej W. Rozycki +@@ -4343,6 +4343,13 @@ P: Maciej W. Rozycki M: ma...@linux-mips.org S: Maintained +TUXONICE (ENHANCED HIBERNATION) +P: Nigel Cunningham +M: ni...@tuxonice.net -+L: suspend2-de...@tuxonice.net ++L: tuxonice-de...@tuxonice.net +W: http://tuxonice.net +S: Maintained + @@ -1725,6 +1728,18 @@ +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("LZF Compression Algorithm"); +MODULE_AUTHOR("Marc Alexander Lehmann & Nigel Cunningham"); +diff --git a/drivers/base/dd.c b/drivers/base/dd.c +index 1352312..f705dce 100644 +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -183,6 +183,7 @@ int wait_for_device_probe(void) + async_synchronize_full(); + return 0; + } ++EXPORT_SYMBOL_GPL(wait_for_device_probe); + + /** + * driver_probe_device - attempt to bind device & driver together diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 2d14f4a..dc9ef3b 100644 --- a/drivers/base/power/main.c @@ -1757,6 +1772,20 @@ /* * For each existing display, we have a pointer to console currently visible +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 88d3368..5817513 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -136,7 +136,8 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) + obj = kcalloc(1, sizeof(*obj), GFP_KERNEL); + + obj->dev = dev; +- obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); ++ obj->filp = shmem_file_setup("drm mm object", size, ++ VM_NORESERVE | VM_ATOMIC_COPY); + if (IS_ERR(obj->filp)) { + kfree(obj); + return NULL; diff --git a/drivers/md/md.c b/drivers/md/md.c index a307f87..6eb04ea 100644 --- a/drivers/md/md.c @@ -1820,7 +1849,7 @@ if (kthread_should_stop()) goto interrupted; diff --git a/fs/buffer.c b/fs/buffer.c -index 9f69741..0c43444 100644 +index 891e1c7..cb8c84a 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -310,6 +310,93 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb) @@ -2374,7 +2403,7 @@ static inline void freezer_do_not_count(void) {} static inline void freezer_count(void) {} diff --git a/include/linux/fs.h b/include/linux/fs.h -index 92734c0..c7e066a 100644 +index 92734c0..249df0f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -8,6 +8,7 @@ @@ -2401,7 +2430,16 @@ #define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31) -@@ -1216,8 +1219,11 @@ enum { +@@ -167,6 +170,8 @@ struct inodes_stat_t { + #define S_NOCMTIME 128 /* Do not update file c/mtime */ + #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */ + #define S_PRIVATE 512 /* Inode is fs-internal */ ++#define S_ATOMIC_COPY 1024 /* Pages mapped with this inode need to be ++ atomically copied (gem) */ + + /* + * Note that nosuid etc flags are inode-specific: setting some file-system +@@ -1216,8 +1221,11 @@ enum { SB_FREEZE_TRANS = 2, }; @@ -2416,10 +2454,18 @@ #define get_fs_excl() atomic_inc(¤t->fs_excl) #define put_fs_excl() atomic_dec(¤t->fs_excl) diff --git a/include/linux/mm.h b/include/linux/mm.h -index 065cdf8..1f4e138 100644 +index 065cdf8..175f46d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -1294,6 +1294,7 @@ int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *, +@@ -104,6 +104,7 @@ extern unsigned int kobjsize(const void *objp); + #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */ + #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */ + #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */ ++#define VM_ATOMIC_COPY 0x40000000 /* This VM should be atomically copied by TuxOnIce */ + + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS +@@ -1294,6 +1295,7 @@ int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, unsigned long lru_pages); @@ -2441,30 +2487,10 @@ #define MAX_LINKS 32 diff --git a/include/linux/suspend.h b/include/linux/suspend.h -index c7d9bb1..47441b6 100644 +index c7d9bb1..8e7de98 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h -@@ -13,6 +13,7 @@ - - #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) - extern void pm_set_vt_switch(int); -+extern int pm_get_vt_switch(void); - extern int pm_prepare_console(void); - extern void pm_restore_console(void); - #else -@@ -20,6 +21,11 @@ static inline void pm_set_vt_switch(int do_switch) - { - } - -+static inline int pm_get_vt_switch(void) -+{ -+ return 0; -+} -+ - static inline int pm_prepare_console(void) - { - return 0; -@@ -295,4 +301,70 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e) +@@ -295,4 +295,70 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e) extern struct mutex pm_mutex; @@ -2657,7 +2683,7 @@ static void helper_lock(void) { diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig -index 23bd4da..57bade3 100644 +index 23bd4da..2520b0e 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -38,6 +38,13 @@ config CAN_PM_TRACE @@ -2757,7 +2783,7 @@ + + config TOI_USERUI_DEFAULT_PATH + string "Default userui program location" -+ default "/usr/local/sbin/tuxonice_fbsplash" ++ default "/usr/local/sbin/tuxoniceui_text" + depends on TOI_USERUI + ---help--- + This entry allows you to specify a default path to the userui binary. @@ -2972,37 +2998,6 @@ obj-$(CONFIG_PM) += main.o obj-$(CONFIG_PM_SLEEP) += console.o obj-$(CONFIG_FREEZER) += process.o -diff --git a/kernel/power/console.c b/kernel/power/console.c -index a3961b2..18ffa1c 100644 ---- a/kernel/power/console.c -+++ b/kernel/power/console.c -@@ -31,6 +31,12 @@ void pm_set_vt_switch(int do_switch) - } - EXPORT_SYMBOL(pm_set_vt_switch); - -+int pm_get_vt_switch(void) -+{ -+ return disable_vt_switch; -+} -+EXPORT_SYMBOL(pm_get_vt_switch); -+ - int pm_prepare_console(void) - { - acquire_console_sem(); -@@ -68,6 +74,7 @@ int pm_prepare_console(void) - kmsg_redirect = SUSPEND_CONSOLE; - return 0; - } -+EXPORT_SYMBOL_GPL(pm_prepare_console); - - void pm_restore_console(void) - { -@@ -86,4 +93,5 @@ void pm_restore_console(void) - - kmsg_redirect = orig_kmsg; - } -+EXPORT_SYMBOL_GPL(pm_restore_console); - #endif diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 4a4a206..4b8067e 100644 --- a/kernel/power/disk.c @@ -3223,7 +3218,7 @@ /** * state - control system power state. diff --git a/kernel/power/power.h b/kernel/power/power.h -index 46b5ec7..d9d8196 100644 +index 46b5ec7..f946b3b 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -1,3 +1,10 @@ @@ -3237,26 +3232,14 @@ #include <linux/suspend.h> #include <linux/suspend_ioctls.h> #include <linux/utsname.h> -@@ -21,18 +28,22 @@ struct swsusp_info { - extern int arch_hibernation_header_save(void *addr, unsigned int max_size); - extern int arch_hibernation_header_restore(void *addr); - --static inline int init_header_complete(struct swsusp_info *info) -+static inline int init_swsusp_header_complete(struct swsusp_info *info) - { - return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE); - } - --static inline char *check_image_kernel(struct swsusp_info *info) -+static inline char *check_swsusp_image_kernel(struct swsusp_info *info) - { +@@ -31,8 +38,12 @@ static inline char *check_image_kernel(struct swsusp_info *info) return arch_hibernation_header_restore(info) ? "architecture specific data" : NULL; } +#else -+extern char *check_swsusp_image_kernel(struct swsusp_info *info); ++extern char *check_image_kernel(struct swsusp_info *info); #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ -+extern int init_swsusp_header(struct swsusp_info *info); ++extern int init_header(struct swsusp_info *info); +extern char resume_file[256]; /* @@ -3473,7 +3456,7 @@ + */ +EXPORT_SYMBOL_GPL(thaw_kernel_threads); diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c -index f5fc2d7..e7e781a 100644 +index f5fc2d7..63959e7 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -34,6 +34,8 @@ @@ -3895,7 +3878,7 @@ #ifndef CONFIG_ARCH_HIBERNATION_HEADER -static int init_header_complete(struct swsusp_info *info) -+int init_swsusp_header_complete(struct swsusp_info *info) ++int init_header_complete(struct swsusp_info *info) { memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname)); info->version_code = LINUX_VERSION_CODE; @@ -3903,7 +3886,7 @@ } -static char *check_image_kernel(struct swsusp_info *info) -+char *check_swsusp_image_kernel(struct swsusp_info *info) ++char *check_image_kernel(struct swsusp_info *info) { if (info->version_code != LINUX_VERSION_CODE) return "kernel version"; @@ -3911,7 +3894,7 @@ return "machine"; return NULL; } -+EXPORT_SYMBOL_GPL(check_swsusp_image_kernel); ++EXPORT_SYMBOL_GPL(check_image_kernel); #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ unsigned long snapshot_get_image_size(void) @@ -3920,45 +3903,24 @@ } -static int init_header(struct swsusp_info *info) -+int init_swsusp_header(struct swsusp_info *info) ++int init_header(struct swsusp_info *info) { memset(info, 0, sizeof(struct swsusp_info)); info->num_physpages = num_physpages; -@@ -1289,8 +1416,9 @@ static int init_header(struct swsusp_info *info) - info->pages = snapshot_get_image_size(); - info->size = info->pages; +@@ -1291,6 +1418,7 @@ static int init_header(struct swsusp_info *info) info->size <<= PAGE_SHIFT; -- return init_header_complete(info); -+ return init_swsusp_header_complete(info); + return init_header_complete(info); } -+EXPORT_SYMBOL_GPL(init_swsusp_header); ++EXPORT_SYMBOL_GPL(init_header); /** * pack_pfns - pfns corresponding to the set bits found in the bitmap @bm -@@ -1345,7 +1473,7 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count) - if (!handle->offset) { - int error; - -- error = init_header((struct swsusp_info *)buffer); -+ error = init_swsusp_header((struct swsusp_info *)buffer); - if (error) - return error; - handle->buffer = buffer; -@@ -1442,7 +1570,7 @@ static int check_header(struct swsusp_info *info) - { - char *reason; - -- reason = check_image_kernel(info); -+ reason = check_swsusp_image_kernel(info); - if (!reason && info->num_physpages != num_physpages) - reason = "memory size"; - if (reason) { diff --git a/kernel/power/tuxonice.h b/kernel/power/tuxonice.h new file mode 100644 -index 0000000..7cfba2a +index 0000000..336049f --- /dev/null +++ b/kernel/power/tuxonice.h -@@ -0,0 +1,212 @@ +@@ -0,0 +1,211 @@ +/* + * kernel/power/tuxonice.h + * @@ -3981,7 +3943,7 @@ +#include <asm/setup.h> +#include "tuxonice_pageflags.h" + -+#define TOI_CORE_VERSION "3.0-rc8-20090313" ++#define TOI_CORE_VERSION "3.0" + +#define MY_BOOT_KERNEL_DATA_VERSION 1 + @@ -4014,7 +3976,6 @@ + TOI_TEST_FILTER_SPEED, + TOI_TEST_BIO, + TOI_NO_PAGESET2, -+ TOI_PM_PREPARE_CONSOLE, + TOI_IGNORE_ROOTFS, + TOI_REPLACE_SWSUSP, + TOI_PAGESET2_FULL, @@ -4523,10 +4484,10 @@ +#endif diff --git a/kernel/power/tuxonice_atomic_copy.c b/kernel/power/tuxonice_atomic_copy.c new file mode 100644 -index 0000000..b891c53 +index 0000000..aff8177 --- /dev/null +++ b/kernel/power/tuxonice_atomic_copy.c -@@ -0,0 +1,422 @@ +@@ -0,0 +1,420 @@ +/* + * kernel/power/tuxonice_atomic_copy.c + * @@ -4832,8 +4793,6 @@ +#ifdef CONFIG_HIGHMEM + free_pbe_list(&restore_highmem_pblist, 1); +#endif -+ if (test_action_state(TOI_PM_PREPARE_CONSOLE)) -+ pm_restore_console(); + toi_running = 0; + return 1; +} @@ -4980,10 +4939,10 @@ +void toi_end_atomic(int stage, int toi_time, int error); diff --git a/kernel/power/tuxonice_block_io.c b/kernel/power/tuxonice_block_io.c new file mode 100644 -index 0000000..f073a0b +index 0000000..dfa3448 --- /dev/null +++ b/kernel/power/tuxonice_block_io.c -@@ -0,0 +1,1325 @@ +@@ -0,0 +1,1305 @@ +/* + * kernel/power/tuxonice_block_io.c + * @@ -5502,8 +5461,35 @@ +static int go_next_page(int writing) +{ + int i, max = (toi_writer_posn.current_chain == -1) ? 1 : -+ toi_devinfo[toi_writer_posn.current_chain].blocks_per_page; ++ toi_devinfo[toi_writer_posn.current_chain].blocks_per_page, ++ compare_to = 0; ++ ++ /* Have we already used the last page of the stream? */ ++ switch (current_stream) { ++ case 0: ++ compare_to = 2; ++ break; ++ case 1: ++ compare_to = 3; ++ break; ++ case 2: ++ compare_to = 1; ++ break; ++ } + ++ if (toi_writer_posn.current_chain == ++ toi_writer_posn_save[compare_to].chain_num && ++ toi_writer_posn.current_offset == ++ toi_writer_posn_save[compare_to].offset) { ++ if (writing) ++ BUG_ON(!current_stream); ++ else { ++ more_readahead = 0; ++ return -ENODATA; ++ } ++ } ++ ++ /* Nope. Go foward a page - or maybe two */ + for (i = 0; i < max; i++) + toi_extent_state_next(&toi_writer_posn); + @@ -5551,56 +5537,16 @@ + int is_readahead, int free_group) +{ + struct toi_bdev_info *dev_info; -+ int result; + -+ if (go_next_page(writing)) { -+ printk(KERN_INFO "Failed to advance a page in the extent " -+ "data.\n"); ++ if (go_next_page(writing)) + return -ENODATA; -+ } -+ -+ if (current_stream == 0 && writing && -+ toi_writer_posn.current_chain == -+ toi_writer_posn_save[2].chain_num && -+ toi_writer_posn.current_offset == -+ toi_writer_posn_save[2].offset) { -+ dump_block_chains(); -+ BUG(); -+ } + + dev_info = &toi_devinfo[toi_writer_posn.current_chain]; + -+ result = toi_do_io(writing, dev_info->bdev, ++ return toi_do_io(writing, dev_info->bdev, + toi_writer_posn.current_offset << <<Diff was trimmed, longer than 597 lines>> ---- CVS-web: http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/SOURCES/kernel-tuxonice.patch?r1=1.2&r2=1.3&f=u _______________________________________________ pld-cvs-commit mailing list pld-cvs-commit@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit