--- /dev/null
+From 043bcbe5ec51e0478ef2b44acef17193e01d7f70 Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hughd@google.com>
+Date: Tue, 10 Jan 2012 15:08:33 -0800
+Subject: mm: test PageSwapBacked in lumpy reclaim
+
+From: Hugh Dickins <hughd@google.com>
+
+commit 043bcbe5ec51e0478ef2b44acef17193e01d7f70 upstream.
+
+Stable note: Not tracked in Bugzilla. There were reports of shared
+ mapped pages being unfairly reclaimed in comparison to older kernels.
+ This is being addressed over time. Even though the subject
+ refers to lumpy reclaim, it impacts compaction as well.
+
+Lumpy reclaim does well to stop at a PageAnon when there's no swap, but
+better is to stop at any PageSwapBacked, which includes shmem/tmpfs too.
+
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Reviewed-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+
+---
+ mm/vmscan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -1199,7 +1199,7 @@ static unsigned long isolate_lru_pages(u
+ * anon page which don't already have a swap slot is
+ * pointless.
+ */
+- if (nr_swap_pages <= 0 && PageAnon(cursor_page) &&
++ if (nr_swap_pages <= 0 && PageSwapBacked(cursor_page) &&
+ !PageSwapCache(cursor_page))
+ break;
+
--- /dev/null
+From 0cee34fd72c582b4f8ad8ce00645b75fb4168199 Mon Sep 17 00:00:00 2001
+From: Mel Gorman <mgorman@suse.de>
+Date: Thu, 12 Jan 2012 17:19:49 -0800
+Subject: mm: vmscan: check if reclaim should really abort even if compaction_ready() is true for one zone
+
+From: Mel Gorman <mgorman@suse.de>
+
+commit 0cee34fd72c582b4f8ad8ce00645b75fb4168199 upstream.
+
+Stable note: Not tracked on Bugzilla. THP and compaction was found to
+ aggressively reclaim pages and stall systems under different
+ situations that was addressed piecemeal over time.
+
+If compaction can proceed for a given zone, shrink_zones() does not
+reclaim any more pages from it. After commit [e0c2327: vmscan: abort
+reclaim/compaction if compaction can proceed], do_try_to_free_pages()
+tries to finish as soon as possible once one zone can compact.
+
+This was intended to prevent slabs being shrunk unnecessarily but there
+are side-effects. One is that a small zone that is ready for compaction
+will abort reclaim even if the chances of successfully allocating a THP
+from that zone is small. It also means that reclaim can return too early
+even though sc->nr_to_reclaim pages were not reclaimed.
+
+This partially reverts the commit until it is proven that slabs are really
+being shrunk unnecessarily but preserves the check to return 1 to avoid
+OOM if reclaim was aborted prematurely.
+
+[aarcange@redhat.com: This patch replaces a revert from Andrea]
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+Reviewed-by: Rik van Riel <riel@redhat.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Minchan Kim <minchan.kim@gmail.com>
+Cc: Dave Jones <davej@redhat.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Andy Isaacson <adi@hexapodia.org>
+Cc: Nai Xia <nai.xia@gmail.com>
+Cc: Johannes Weiner <jweiner@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/vmscan.c | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2129,7 +2129,8 @@ static inline bool compaction_ready(stru
+ *
+ * This function returns true if a zone is being reclaimed for a costly
+ * high-order allocation and compaction is ready to begin. This indicates to
+- * the caller that it should retry the allocation or fail.
++ * the caller that it should consider retrying the allocation instead of
++ * further reclaim.
+ */
+ static bool shrink_zones(int priority, struct zonelist *zonelist,
+ struct scan_control *sc)
+@@ -2138,7 +2139,7 @@ static bool shrink_zones(int priority, s
+ struct zone *zone;
+ unsigned long nr_soft_reclaimed;
+ unsigned long nr_soft_scanned;
+- bool should_abort_reclaim = false;
++ bool aborted_reclaim = false;
+
+ for_each_zone_zonelist_nodemask(zone, z, zonelist,
+ gfp_zone(sc->gfp_mask), sc->nodemask) {
+@@ -2164,7 +2165,7 @@ static bool shrink_zones(int priority, s
+ * allocations.
+ */
+ if (compaction_ready(zone, sc)) {
+- should_abort_reclaim = true;
++ aborted_reclaim = true;
+ continue;
+ }
+ }
+@@ -2186,7 +2187,7 @@ static bool shrink_zones(int priority, s
+ shrink_zone(priority, zone, sc);
+ }
+
+- return should_abort_reclaim;
++ return aborted_reclaim;
+ }
+
+ static bool zone_reclaimable(struct zone *zone)
+@@ -2240,7 +2241,7 @@ static unsigned long do_try_to_free_page
+ struct zoneref *z;
+ struct zone *zone;
+ unsigned long writeback_threshold;
+- bool should_abort_reclaim;
++ bool aborted_reclaim;
+
+ get_mems_allowed();
+ delayacct_freepages_start();
+@@ -2252,9 +2253,7 @@ static unsigned long do_try_to_free_page
+ sc->nr_scanned = 0;
+ if (!priority)
+ disable_swap_token(sc->mem_cgroup);
+- should_abort_reclaim = shrink_zones(priority, zonelist, sc);
+- if (should_abort_reclaim)
+- break;
++ aborted_reclaim = shrink_zones(priority, zonelist, sc);
+
+ /*
+ * Don't shrink slabs when reclaiming memory from
+@@ -2320,8 +2319,8 @@ out:
+ if (oom_killer_disabled)
+ return 0;
+
+- /* Aborting reclaim to try compaction? don't OOM, then */
+- if (should_abort_reclaim)
++ /* Aborted reclaim to try compaction? don't OOM, then */
++ if (aborted_reclaim)
+ return 1;
+
+ /* top priority shrink_zones still had more to do? don't OOM, then */
--- /dev/null
+From 7335084d446b83cbcb15da80497d03f0c1dc9e21 Mon Sep 17 00:00:00 2001
+From: Mel Gorman <mgorman@suse.de>
+Date: Thu, 12 Jan 2012 17:19:33 -0800
+Subject: mm: vmscan: do not OOM if aborting reclaim to start compaction
+
+From: Mel Gorman <mgorman@suse.de>
+
+commit 7335084d446b83cbcb15da80497d03f0c1dc9e21 upstream.
+
+Stable note: Not tracked in Bugzilla. This patch makes later patches
+ easier to apply but otherwise has little to justify it. The
+ problem it fixes was never observed but the source of the
+ theoretical problem did not exist for very long.
+
+During direct reclaim it is possible that reclaim will be aborted so that
+compaction can be attempted to satisfy a high-order allocation. If this
+decision is made before any pages are reclaimed, it is possible that 0 is
+returned to the page allocator potentially triggering an OOM. This has
+not been observed but it is a possibility so this patch addresses it.
+
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+Reviewed-by: Rik van Riel <riel@redhat.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Minchan Kim <minchan.kim@gmail.com>
+Cc: Dave Jones <davej@redhat.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Andy Isaacson <adi@hexapodia.org>
+Cc: Nai Xia <nai.xia@gmail.com>
+Cc: Johannes Weiner <jweiner@redhat.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@linuxfoundation.org>
+
+
+---
+ mm/vmscan.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2240,6 +2240,7 @@ static unsigned long do_try_to_free_page
+ struct zoneref *z;
+ struct zone *zone;
+ unsigned long writeback_threshold;
++ bool should_abort_reclaim;
+
+ get_mems_allowed();
+ delayacct_freepages_start();
+@@ -2251,7 +2252,8 @@ static unsigned long do_try_to_free_page
+ sc->nr_scanned = 0;
+ if (!priority)
+ disable_swap_token(sc->mem_cgroup);
+- if (shrink_zones(priority, zonelist, sc))
++ should_abort_reclaim = shrink_zones(priority, zonelist, sc);
++ if (should_abort_reclaim)
+ break;
+
+ /*
+@@ -2318,6 +2320,10 @@ out:
+ if (oom_killer_disabled)
+ return 0;
+
++ /* Aborting reclaim to try compaction? don't OOM, then */
++ if (should_abort_reclaim)
++ return 1;
++
+ /* top priority shrink_zones still had more to do? don't OOM, then */
+ if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc))
+ return 1;
--- /dev/null
+From 86cfd3a45042ab242d47f3935a02811a402beab6 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Tue, 10 Jan 2012 15:08:18 -0800
+Subject: mm/vmscan.c: consider swap space when deciding whether to continue reclaim
+
+From: Minchan Kim <minchan@kernel.org>
+
+commit 86cfd3a45042ab242d47f3935a02811a402beab6 upstream.
+
+Stable note: Not tracked in Bugzilla. This patch reduces kswapd CPU
+ usage on swapless systems with high anonymous memory usage.
+
+It's pointless to continue reclaiming when we have no swap space and lots
+of anon pages in the inactive list.
+
+Without this patch, it is possible when swap is disabled to continue
+trying to reclaim when there are only anonymous pages in the system even
+though that will not make any progress.
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Acked-by: Mel Gorman <mgorman@suse.de>
+Reviewed-by: Rik van Riel <riel@redhat.com>
+Cc: Johannes Weiner <jweiner@redhat.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/vmscan.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2008,8 +2008,9 @@ static inline bool should_continue_recla
+ * inactive lists are large enough, continue reclaiming
+ */
+ pages_for_compaction = (2UL << sc->order);
+- inactive_lru_pages = zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON) +
+- zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE);
++ inactive_lru_pages = zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE);
++ if (nr_swap_pages > 0)
++ inactive_lru_pages += zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON);
+ if (sc->nr_reclaimed < pages_for_compaction &&
+ inactive_lru_pages > pages_for_compaction)
+ return true;
kswapd-assign-new_order-and-new_classzone_idx-after-wakeup-in-sleeping.patch
mm-compaction-introduce-sync-light-migration-for-use-by-compaction.patch
mm-vmscan-when-reclaiming-for-compaction-ensure-there-are-sufficient-free-pages-available.patch
+mm-vmscan-do-not-oom-if-aborting-reclaim-to-start-compaction.patch
+mm-vmscan-check-if-reclaim-should-really-abort-even-if-compaction_ready-is-true-for-one-zone.patch
+vmscan-promote-shared-file-mapped-pages.patch
+vmscan-activate-executable-pages-after-first-usage.patch
+mm-vmscan.c-consider-swap-space-when-deciding-whether-to-continue-reclaim.patch
+mm-test-pageswapbacked-in-lumpy-reclaim.patch
--- /dev/null
+From c909e99364c8b6ca07864d752950b6b4ecf6bef4 Mon Sep 17 00:00:00 2001
+From: Konstantin Khlebnikov <khlebnikov@openvz.org>
+Date: Tue, 10 Jan 2012 15:07:03 -0800
+Subject: vmscan: activate executable pages after first usage
+
+From: Konstantin Khlebnikov <khlebnikov@openvz.org>
+
+commit c909e99364c8b6ca07864d752950b6b4ecf6bef4 upstream.
+
+Stable note: Not tracked in Bugzilla. There were reports of shared
+ mapped pages being unfairly reclaimed in comparison to older kernels.
+ This is being addressed over time.
+
+Logic added in commit 8cab4754d24a0 ("vmscan: make mapped executable pages
+the first class citizen") was noticeably weakened in commit
+645747462435d84 ("vmscan: detect mapped file pages used only once").
+
+Currently these pages can become "first class citizens" only after second
+usage. After this patch page_check_references() will activate they after
+first usage, and executable code gets yet better chance to stay in memory.
+
+Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
+Cc: Pekka Enberg <penberg@kernel.org>
+Cc: Minchan Kim <minchan.kim@gmail.com>
+Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Cc: Wu Fengguang <fengguang.wu@intel.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Nick Piggin <npiggin@kernel.dk>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Shaohua Li <shaohua.li@intel.com>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/vmscan.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -726,6 +726,12 @@ static enum page_references page_check_r
+ if (referenced_page || referenced_ptes > 1)
+ return PAGEREF_ACTIVATE;
+
++ /*
++ * Activate file-backed executable pages after first usage.
++ */
++ if (vm_flags & VM_EXEC)
++ return PAGEREF_ACTIVATE;
++
+ return PAGEREF_KEEP;
+ }
+
--- /dev/null
+From 34dbc67a644f11ab3475d822d72e25409911e760 Mon Sep 17 00:00:00 2001
+From: Konstantin Khlebnikov <khlebnikov@openvz.org>
+Date: Tue, 10 Jan 2012 15:06:59 -0800
+Subject: vmscan: promote shared file mapped pages
+
+From: Konstantin Khlebnikov <khlebnikov@openvz.org>
+
+commit 34dbc67a644f11ab3475d822d72e25409911e760 upstream.
+
+Stable note: Not tracked in Bugzilla. There were reports of shared
+ mapped pages being unfairly reclaimed in comparison to older kernels.
+ This is being addressed over time. The specific workload being
+ addressed here in described in paragraph four and while paragraph
+ five says it did not help performance as such, it made a difference
+ to major page faults. I'm aware of at least one bug for a large
+ vendor that was due to increased major faults.
+
+Commit 645747462435 ("vmscan: detect mapped file pages used only once")
+greatly decreases lifetime of single-used mapped file pages.
+Unfortunately it also decreases life time of all shared mapped file
+pages. Because after commit bf3f3bc5e7347 ("mm: don't mark_page_accessed
+in fault path") page-fault handler does not mark page active or even
+referenced.
+
+Thus page_check_references() activates file page only if it was used twice
+while it stays in inactive list, meanwhile it activates anon pages after
+first access. Inactive list can be small enough, this way reclaimer can
+accidentally throw away any widely used page if it wasn't used twice in
+short period.
+
+After this patch page_check_references() also activate file mapped page at
+first inactive list scan if this page is already used multiple times via
+several ptes.
+
+I found this while trying to fix degragation in rhel6 (~2.6.32) from rhel5
+(~2.6.18). There a complete mess with >100 web/mail/spam/ftp containers,
+they share all their files but there a lot of anonymous pages: ~500mb
+shared file mapped memory and 15-20Gb non-shared anonymous memory. In
+this situation major-pagefaults are very costly, because all containers
+share the same page. In my load kernel created a disproportionate
+pressure on the file memory, compared with the anonymous, they equaled
+only if I raise swappiness up to 150 =)
+
+These patches actually wasn't helped a lot in my problem, but I saw
+noticable (10-20 times) reduce in count and average time of
+major-pagefault in file-mapped areas.
+
+Actually both patches are fixes for commit v2.6.33-5448-g6457474, because
+it was aimed at one scenario (singly used pages), but it breaks the logic
+in other scenarios (shared and/or executable pages)
+
+Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
+Acked-by: Pekka Enberg <penberg@kernel.org>
+Acked-by: Minchan Kim <minchan.kim@gmail.com>
+Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Cc: Wu Fengguang <fengguang.wu@intel.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Nick Piggin <npiggin@kernel.dk>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Shaohua Li <shaohua.li@intel.com>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Mel Gorman <mgorman@suse.de>
+
+---
+ mm/vmscan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -723,7 +723,7 @@ static enum page_references page_check_r
+ */
+ SetPageReferenced(page);
+
+- if (referenced_page)
++ if (referenced_page || referenced_ptes > 1)
+ return PAGEREF_ACTIVATE;
+
+ return PAGEREF_KEEP;