- swsusp-write-speedup.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     swsusp: write speedup

has been removed from the -mm tree.  Its filename is

     swsusp-write-speedup.patch

This patch was dropped because it was merged into mainline or a subsystem tree

------------------------------------------------------
Subject: swsusp: write speedup
From: Andrew Morton <akpm@xxxxxxxx>

Switch the swsusp writeout code from 4k-at-a-time to 4MB-at-a-time.

Crufty old PIII testbox:
	12.9 MB/s -> 20.9 MB/s

Sony Vaio:
	14.7 MB/s -> 26.5 MB/s

The implementation is crude.  A better one would use larger BIOs, but wouldn't
gain any performance.

The memcpys will be mostly pipelined with the IO and basically come for free.

The ENOMEM path has not been tested.  It should be.

Cc: Pavel Machek <pavel@xxxxxx>
Cc: "Rafael J. Wysocki" <rjw@xxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 include/linux/swap.h |    5 +-
 kernel/power/swap.c  |   93 +++++++++++++++++++++++++++++++++--------
 mm/page_io.c         |   23 +++++++---
 3 files changed, 97 insertions(+), 24 deletions(-)

diff -puN include/linux/swap.h~swsusp-write-speedup include/linux/swap.h
--- a/include/linux/swap.h~swsusp-write-speedup
+++ a/include/linux/swap.h
@@ -12,6 +12,8 @@
 
 struct notifier_block;
 
+struct bio;
+
 #define SWAP_FLAG_PREFER	0x8000	/* set if swap priority specified */
 #define SWAP_FLAG_PRIO_MASK	0x7fff
 #define SWAP_FLAG_PRIO_SHIFT	0
@@ -216,7 +218,8 @@ extern void swap_unplug_io_fn(struct bac
 /* linux/mm/page_io.c */
 extern int swap_readpage(struct file *, struct page *);
 extern int swap_writepage(struct page *page, struct writeback_control *wbc);
-extern int rw_swap_page_sync(int, swp_entry_t, struct page *);
+extern int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page,
+				struct bio **bio_chain);
 
 /* linux/mm/swap_state.c */
 extern struct address_space swapper_space;
diff -puN kernel/power/swap.c~swsusp-write-speedup kernel/power/swap.c
--- a/kernel/power/swap.c~swsusp-write-speedup
+++ a/kernel/power/swap.c
@@ -49,18 +49,16 @@ static int mark_swapfiles(swp_entry_t st
 {
 	int error;
 
-	rw_swap_page_sync(READ,
-			  swp_entry(root_swap, 0),
-			  virt_to_page((unsigned long)&swsusp_header));
+	rw_swap_page_sync(READ, swp_entry(root_swap, 0),
+			  virt_to_page((unsigned long)&swsusp_header), NULL);
 	if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
 	    !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
 		memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
 		memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
 		swsusp_header.image = start;
-		error = rw_swap_page_sync(WRITE,
-					  swp_entry(root_swap, 0),
-					  virt_to_page((unsigned long)
-						       &swsusp_header));
+		error = rw_swap_page_sync(WRITE, swp_entry(root_swap, 0),
+				virt_to_page((unsigned long)&swsusp_header),
+				NULL);
 	} else {
 		pr_debug("swsusp: Partition is not swap space.\n");
 		error = -ENODEV;
@@ -88,16 +86,37 @@ static int swsusp_swap_check(void) /* Th
  *	write_page - Write one page to given swap location.
  *	@buf:		Address we're writing.
  *	@offset:	Offset of the swap page we're writing to.
+ *	@bio_chain:	Link the next write BIO here
  */
 
-static int write_page(void *buf, unsigned long offset)
+static int write_page(void *buf, unsigned long offset, struct bio **bio_chain)
 {
 	swp_entry_t entry;
 	int error = -ENOSPC;
 
 	if (offset) {
+		struct page *page = virt_to_page(buf);
+
+		if (bio_chain) {
+			/*
+			 * Whether or not we successfully allocated a copy page,
+			 * we take a ref on the page here.  It gets undone in
+			 * wait_on_bio_chain().
+			 */
+			struct page *page_copy;
+			page_copy = alloc_page(GFP_ATOMIC);
+			if (page_copy == NULL) {
+				WARN_ON_ONCE(1);
+				bio_chain = NULL;	/* Go synchronous */
+				get_page(page);
+			} else {
+				memcpy(page_address(page_copy),
+					page_address(page), PAGE_SIZE);
+				page = page_copy;
+			}
+		}
 		entry = swp_entry(root_swap, offset);
-		error = rw_swap_page_sync(WRITE, entry, virt_to_page(buf));
+		error = rw_swap_page_sync(WRITE, entry, page, bio_chain);
 	}
 	return error;
 }
@@ -185,37 +204,68 @@ static int get_swap_writer(struct swap_m
 	return 0;
 }
 
-static int swap_write_page(struct swap_map_handle *handle, void *buf)
+static int wait_on_bio_chain(struct bio **bio_chain)
 {
-	int error;
+	struct bio *bio;
+	struct bio *next_bio;
+	int ret = 0;
+
+	if (bio_chain == NULL)
+		return 0;
+
+	bio = *bio_chain;
+	while (bio) {
+		struct page *page;
+
+		next_bio = bio->bi_private;
+		page = bio->bi_io_vec[0].bv_page;
+		wait_on_page_locked(page);
+		if (!PageUptodate(page) || PageError(page))
+			ret = -EIO;
+		put_page(page);
+		bio_put(bio);
+		bio = next_bio;
+	}
+	*bio_chain = NULL;
+	return ret;
+}
+
+static int swap_write_page(struct swap_map_handle *handle, void *buf,
+				struct bio **bio_chain)
+{
+	int error = 0;
 	unsigned long offset;
 
 	if (!handle->cur)
 		return -EINVAL;
 	offset = alloc_swap_page(root_swap, handle->bitmap);
-	error = write_page(buf, offset);
+	error = write_page(buf, offset, bio_chain);
 	if (error)
 		return error;
 	handle->cur->entries[handle->k++] = offset;
 	if (handle->k >= MAP_PAGE_ENTRIES) {
+		error = wait_on_bio_chain(bio_chain);
+		if (error)
+			goto out;
 		offset = alloc_swap_page(root_swap, handle->bitmap);
 		if (!offset)
 			return -ENOSPC;
 		handle->cur->next_swap = offset;
-		error = write_page(handle->cur, handle->cur_swap);
+		error = write_page(handle->cur, handle->cur_swap, NULL);
 		if (error)
-			return error;
+			goto out;
 		memset(handle->cur, 0, PAGE_SIZE);
 		handle->cur_swap = offset;
 		handle->k = 0;
 	}
-	return 0;
+out:
+	return error;
 }
 
 static int flush_swap_writer(struct swap_map_handle *handle)
 {
 	if (handle->cur && handle->cur_swap)
-		return write_page(handle->cur, handle->cur_swap);
+		return write_page(handle->cur, handle->cur_swap, NULL);
 	else
 		return -EINVAL;
 }
@@ -232,6 +282,8 @@ static int save_image(struct swap_map_ha
 	int ret;
 	int error = 0;
 	int nr_pages;
+	int err2;
+	struct bio *bio;
 	struct timeval start;
 	struct timeval stop;
 
@@ -240,11 +292,13 @@ static int save_image(struct swap_map_ha
 	if (!m)
 		m = 1;
 	nr_pages = 0;
+	bio = NULL;
 	do_gettimeofday(&start);
 	do {
 		ret = snapshot_read_next(snapshot, PAGE_SIZE);
 		if (ret > 0) {
-			error = swap_write_page(handle, data_of(*snapshot));
+			error = swap_write_page(handle, data_of(*snapshot),
+						&bio);
 			if (error)
 				break;
 			if (!(nr_pages % m))
@@ -252,8 +306,11 @@ static int save_image(struct swap_map_ha
 			nr_pages++;
 		}
 	} while (ret > 0);
+	err2 = wait_on_bio_chain(&bio);
 	do_gettimeofday(&stop);
 	if (!error)
+		error = err2;
+	if (!error)
 		printk("\b\b\b\bdone\n");
 	show_speed(&start, &stop, nr_to_write, "Wrote");
 	return error;
@@ -307,7 +364,7 @@ int swsusp_write(void)
 	error = get_swap_writer(&handle);
 	if (!error) {
 		unsigned long start = handle.cur_swap;
-		error = swap_write_page(&handle, header);
+		error = swap_write_page(&handle, header, NULL);
 		if (!error)
 			error = save_image(&handle, &snapshot,
 					header->pages - 1);
diff -puN mm/page_io.c~swsusp-write-speedup mm/page_io.c
--- a/mm/page_io.c~swsusp-write-speedup
+++ a/mm/page_io.c
@@ -156,10 +156,12 @@ out:
  * We use end_swap_bio_read() even for writes, because it happens to do what
  * we want.
  */
-int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page)
+int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page,
+			struct bio **bio_chain)
 {
 	struct bio *bio;
 	int ret = 0;
+	int bio_rw;
 
 	lock_page(page);
 
@@ -170,11 +172,22 @@ int rw_swap_page_sync(int rw, swp_entry_
 		goto out;
 	}
 
-	submit_bio(rw | (1 << BIO_RW_SYNC), bio);
-	wait_on_page_locked(page);
+	bio_rw = rw;
+	if (!bio_chain)
+		bio_rw |= (1 << BIO_RW_SYNC);
+	if (bio_chain)
+		bio_get(bio);
+	submit_bio(bio_rw, bio);
+	if (bio_chain == NULL) {
+		wait_on_page_locked(page);
 
-	if (!PageUptodate(page) || PageError(page))
-		ret = -EIO;
+		if (!PageUptodate(page) || PageError(page))
+			ret = -EIO;
+	}
+	if (bio_chain) {
+		bio->bi_private = *bio_chain;
+		*bio_chain = bio;
+	}
 out:
 	return ret;
 }
_

Patches currently in -mm which might be from akpm@xxxxxxxx are

origin.patch
git-acpi.patch
acpi-asus-s3-resume-fix.patch
sony_apci-resume.patch
kauditd_thread-warning-fix.patch
git-block.patch
git-block-fixup.patch
git-block-hack.patch
git-drm.patch
git-dvb.patch
git-geode-fixup.patch
git-gfs2.patch
git-ia64.patch
git-ieee1394.patch
git-input.patch
git-intelfb-fixup.patch
hdrcheck-permission-fix.patch
mmc-driver-for-ti-flashmedia-card-reader-source.patch
git-mtd-fixup.patch
git-netdev-all.patch
forcedeth-power-management-support-tidy.patch
drivers-net-ns83820c-add-paramter-to-disable-auto.patch
revert-allow-file-systems-to-manually-d_move-inside-of-rename.patch
revert-genirq-core-fix-handle_level_irq.patch
git-parisc-fixup.patch
git-parisc-powerpc-fix.patch
git-pcmcia-fixup.patch
git-serial.patch
git-serial-fixup.patch
serial-fix-uart_bug_txen-test.patch
pcie-check-and-return-bus_register-errors-fix.patch
git-scsi-misc.patch
git-block-vs-git-sas.patch
scsi-device_reprobe-can-fail.patch
git-scsi-target-fixup.patch
git-scsi-target-vs-git-block.patch
gregkh-usb-usb-storage-add-rio-karma-eject-support-fix.patch
xpad-dance-pad-support-tidy.patch
git-watchdog.patch
revert-x86_64-mm-i386-remove-lock-section.patch
fix-x86_64-mm-spinlock-cleanup.patch
arch-i386-pci-mmconfigc-tlb-flush-fix-tweaks.patch
xfs-rename-uio_read.patch
reduce-max_nr_zones-use-enum-to-define-zones-reformat-and-comment-fix.patch
have-x86-use-add_active_range-and-free_area_init_nodes-fix.patch
vm-add-per-zone-writeout-counter.patch
convert-s390-page-handling-macros-to-functions-fix.patch
slab-fix-kmalloc_node-applying-memory-policies-if-nodeid-==-numa_node_id-fix.patch
gfp_thisnode-for-the-slab-allocator-v2-fix.patch
get-rid-of-zone_table-fix.patch
do_no_pfn-tweaks.patch
radix-tree-rcu-lockless-readside.patch
acx1xx-wireless-driver.patch
tiacx-pci-build-fix.patch
tiacx-ia64-fix.patch
tiacx-build-fix.patch
nommu-set-bdi-capabilities-for-dev-mem-and-dev-kmem-tidy.patch
nommu-move-the-fallback-arch_vma_name-to-a-sensible-place-fix.patch
convert-i386-summit-subarch-to-use-srat-info-for-apicid_to_node-calls-tidy.patch
deprecate-smbfs-in-favour-of-cifs.patch
edac-new-opteron-athlon64-memory-controller-driver-tidy.patch
inode_diet-replace-inodeugeneric_ip-with-inodei_private-gfs-fix.patch
inode-diet-eliminate-i_blksize-and-use-a-per-superblock-default-fix-fix.patch
x86-microcode-microcode-driver-cleanup-tidy.patch
x86-microcode-add-sysfs-and-hotplug-support-fix.patch
eisa-bus-modalias-attributes-support-1-fix-git-kbuild-fix.patch
add-address_space_operationsbatch_write-fix.patch
alloc_fdtable-cleanup.patch
sysctl-allow-proc-sys-without-sys_sysctl-fix.patch
add-probe_kernel_address.patch
x86-use-probe_kernel_address-in-handle_bug.patch
blockdevc-check-errors.patch
let-warn_on-warn_on_once-return-the-condition-fix.patch
let-warn_on-warn_on_once-return-the-condition-fix-2.patch
omap-add-watchdog-driver-support-tweaks.patch
move-valid_dma_direction-from-x86_64-to-generic-code-fix.patch
single-bit-flip-detector-tidy.patch
fix-unserialized-task-files-changing-fix.patch
tty-make-termios_sem-a-mutex-fix.patch
solaris-emulation-incorrect-tty-locking-fix.patch
solaris-emulation-incorrect-tty-locking-fix-2.patch
cpuset-top_cpuset-tracks-hotplug-changes-to-node_online_map-fix.patch
remove-sound-oss-copying.patch
maximum-latency-tracking-infrastructure-tidy.patch
fs-nameic-replace-multiple-current-fs-by-shortcut-variable-tidy.patch
call-mm-page-writebackcset_ratelimit-when-new-pages-tidy.patch
sys-modules-patch-allow-full-length-section-names.patch
expand_fdtable-remove-pointless-unlocklock.patch
add-config_headers_check-option-to-automatically-run-make-headers_check-nobble.patch
submit-checklist-mention-headers_check.patch
ntp-move-all-the-ntp-related-code-to-ntpc-fix.patch
reiserfs-on-demand-bitmap-loading.patch
streamline-generic_file_-interfaces-and-filemap-gfs-fix.patch
add-vector-aio-support-fix.patch
csa-basic-accounting-over-taskstats-fix.patch
fs-cache-make-kafs-use-fs-cache-fix.patch
fs-cache-make-kafs-use-fs-cache-vs-streamline-generic_file_-interfaces-and-filemap.patch
nfs-use-local-caching-12-fix.patch
stack-overflow-safe-kdump-crash_use_safe_smp_processor_id-fix.patch
generic-ioremap_page_range-x86_64-conversion-fix.patch
vfs-make-filldir_t-and-struct-kstat-deal-in-64-bit-inode-numbers-alpha-fix.patch
some-cleanup-in-the-pipe-code-tidy.patch
support-piping-into-commands-in-proc-sys-kernel-core_pattern-fix.patch
move-pidmap-to-pspaceh-fix.patch
kprobes-handle-symbol-resolution-when-modulesymbol-is-specified-tidy.patch
isdn-work-around-excessive-udelay.patch
knfsd-add-a-callback-for-when-last-rpc-thread-finishes-tidy.patch
knfsd-add-a-callback-for-when-last-rpc-thread-finishes-fix.patch
knfsd-separate-out-some-parts-of-nfsd_svc-which-start-nfs-servers-tweaks.patch
knfsd-define-new-nfsdfs-file-portlist-contains-list-of-ports-tidy.patch
knfsd-define-new-nfsdfs-file-portlist-contains-list-of-ports-fix.patch
knfsd-drop-serv-option-to-svc_recv-and-svc_process-nfs-callback-fix-nfs-callback-fix.patch
knfsd-move-tempsock-aging-to-a-timer-tidy.patch
sched-remove-unnecessary-sched-group-allocations-fix.patch
swap_prefetch-vs-zoned-counters.patch
ecryptfs-mmap-operations.patch
ecryptfs-alpha-build-fix.patch
ecryptfs-more-elegant-aes-key-size-manipulation.patch
ecryptfs-get_sb_dev-fix.patch
make-kmem_cache_destroy-return-void-ecryptfs.patch
ecryptfs-versioning-fixes-tidy.patch
namespaces-add-nsproxy.patch
namespaces-utsname-switch-to-using-uts-namespaces.patch
namespaces-utsname-switch-to-using-uts-namespaces-klibc-bit-sparc.patch
namespaces-utsname-use-init_utsname-when-appropriate.patch
namespaces-utsname-implement-utsname-namespaces.patch
namespaces-utsname-sysctl-hack.patch
ipc-namespace-core.patch
rename-the-provided-execve-functions-to-kernel_execve-headers-fix.patch
replace-cad_pid-by-a-struct-pid-fixes.patch
readahead-sysctl-parameters-fix.patch
make-copy_from_user_inatomic-not-zero-the-tail-on-i386-vs-reiser4.patch
make-kmem_cache_destroy-return-void-reiser4.patch
reiser4-hardirq-include-fix.patch
reiser4-run-truncate_inode_pages-in-reiser4_delete_inode.patch
reiser4-get_sb_dev-fix.patch
reiser4-vs-zoned-allocator.patch
reiser4-rename-generic_sounding_globalspatch-fix.patch
hpt3xx-rework-rate-filtering-tidy.patch
genirq-convert-the-i386-architecture-to-irq-chips.patch
genirq-x86_64-irq-reenable-migrating-irqs-to-other-cpus.patch
genirq-msi-simplify-msi-enable-and-disable.patch
genirq-ia64-irq-dynamic-irq-support.patch
genirq-msi-only-build-msi-apicc-on-ia64-fix.patch
genirq-i386-irq-remove-the-msi-assumption-that-irq-==-vector.patch
genirq-x86_64-irq-make-vector_irq-per-cpu-fix.patch
genirq-x86_64-irq-make-vector_irq-per-cpu-warning-fix.patch
add-hypertransport-capability-defines-fix.patch
initial-generic-hypertransport-interrupt-support-Kconfig-fix.patch
srcu-report-out-of-memory-errors-fixlet.patch
isdn-debug-build-fix.patch
isdn-more-pr_debug-fixes.patch
nr_blockdev_pages-in_interrupt-warning.patch
device-suspend-debug.patch
slab-leaks3-default-y.patch
x86-kmap_atomic-debugging.patch
restore-rogue-readahead-printk.patch
put_bh-debug.patch
acpi_format_exception-debug.patch
jmicron-warning-fix.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux