--- /dev/null
+From 3399446632739fcd05fd8b272b476a69c6e6d14a Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hughd@google.com>
+Date: Thu, 9 Sep 2010 16:38:11 -0700
+Subject: swap: discard while swapping only if SWAP_FLAG_DISCARD
+
+From: Hugh Dickins <hughd@google.com>
+
+commit 3399446632739fcd05fd8b272b476a69c6e6d14a upstream.
+
+Tests with recent firmware on Intel X25-M 80GB and OCZ Vertex 60GB SSDs
+show a shift since I last tested in December: in part because of firmware
+updates, in part because of the necessary move from barriers to awaiting
+completion at the block layer. While discard at swapon still shows as
+slightly beneficial on both, discarding 1MB swap cluster when allocating
+is now disadvanteous: adds 25% overhead on Intel, adds 230% on OCZ (YMMV).
+
+Surrender: discard as presently implemented is more hindrance than help
+for swap; but might prove useful on other devices, or with improvements.
+So continue to do the discard at swapon, but make discard while swapping
+conditional on a SWAP_FLAG_DISCARD to sys_swapon() (which has been using
+only the lower 16 bits of int flags).
+
+We can add a --discard or -d to swapon(8), and a "discard" to swap in
+/etc/fstab: matching the mount option for btrfs, ext4, fat, gfs2, nilfs2.
+
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Nigel Cunningham <nigel@tuxonice.net>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Jens Axboe <jaxboe@fusionio.com>
+Cc: James Bottomley <James.Bottomley@hansenpartnership.com>
+Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/swap.h | 3 ++-
+ mm/swapfile.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/include/linux/swap.h
++++ b/include/linux/swap.h
+@@ -19,6 +19,7 @@ struct bio;
+ #define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */
+ #define SWAP_FLAG_PRIO_MASK 0x7fff
+ #define SWAP_FLAG_PRIO_SHIFT 0
++#define SWAP_FLAG_DISCARD 0x10000 /* discard swap cluster after use */
+
+ static inline int current_is_kswapd(void)
+ {
+@@ -142,7 +143,7 @@ struct swap_extent {
+ enum {
+ SWP_USED = (1 << 0), /* is slot in swap_info[] used? */
+ SWP_WRITEOK = (1 << 1), /* ok to write to this swap? */
+- SWP_DISCARDABLE = (1 << 2), /* blkdev supports discard */
++ SWP_DISCARDABLE = (1 << 2), /* swapon+blkdev support discard */
+ SWP_DISCARDING = (1 << 3), /* now discarding a free cluster */
+ SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */
+ SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -2050,7 +2050,7 @@ SYSCALL_DEFINE2(swapon, const char __use
+ p->flags |= SWP_SOLIDSTATE;
+ p->cluster_next = 1 + (random32() % p->highest_bit);
+ }
+- if (discard_swap(p) == 0)
++ if (discard_swap(p) == 0 && (swap_flags & SWAP_FLAG_DISCARD))
+ p->flags |= SWP_DISCARDABLE;
+ }
+
--- /dev/null
+From 8f2ae0faa3a119158c4dcfe89926d6fad5f5332c Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@infradead.org>
+Date: Thu, 9 Sep 2010 16:38:10 -0700
+Subject: swap: do not send discards as barriers
+
+From: Christoph Hellwig <hch@infradead.org>
+
+commit 8f2ae0faa3a119158c4dcfe89926d6fad5f5332c upstream.
+
+The swap code already uses synchronous discards, no need to add I/O
+barriers.
+
+This fixes the worst of the terrible slowdown in swap allocation for
+hibernation, reported on 2.6.35 by Nigel Cunningham; but does not entirely
+eliminate that regression.
+
+[tj@kernel.org: superflous newlines removed]
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Tested-by: Nigel Cunningham <nigel@tuxonice.net>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Cc: Jens Axboe <jaxboe@fusionio.com>
+Cc: James Bottomley <James.Bottomley@hansenpartnership.com>
+Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/swapfile.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -139,8 +139,7 @@ static int discard_swap(struct swap_info
+ nr_blocks = ((sector_t)se->nr_pages - 1) << (PAGE_SHIFT - 9);
+ if (nr_blocks) {
+ err = blkdev_issue_discard(si->bdev, start_block,
+- nr_blocks, GFP_KERNEL,
+- BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER);
++ nr_blocks, GFP_KERNEL, BLKDEV_IFL_WAIT);
+ if (err)
+ return err;
+ cond_resched();
+@@ -151,8 +150,7 @@ static int discard_swap(struct swap_info
+ nr_blocks = (sector_t)se->nr_pages << (PAGE_SHIFT - 9);
+
+ err = blkdev_issue_discard(si->bdev, start_block,
+- nr_blocks, GFP_KERNEL,
+- BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER);
++ nr_blocks, GFP_KERNEL, BLKDEV_IFL_WAIT);
+ if (err)
+ break;
+
+@@ -191,8 +189,7 @@ static void discard_swap_cluster(struct
+ start_block <<= PAGE_SHIFT - 9;
+ nr_blocks <<= PAGE_SHIFT - 9;
+ if (blkdev_issue_discard(si->bdev, start_block,
+- nr_blocks, GFP_NOIO, BLKDEV_IFL_WAIT |
+- BLKDEV_IFL_BARRIER))
++ nr_blocks, GFP_NOIO, BLKDEV_IFL_WAIT))
+ break;
+ }
+