+++ /dev/null
-From 84235de394d9775bfaa7fa9762a59d91fef0c1fc Mon Sep 17 00:00:00 2001
-From: Johannes Weiner <hannes@cmpxchg.org>
-Date: Wed, 16 Oct 2013 13:47:00 -0700
-Subject: fs: buffer: move allocation failure loop into the allocator
-
-From: Johannes Weiner <hannes@cmpxchg.org>
-
-commit 84235de394d9775bfaa7fa9762a59d91fef0c1fc upstream.
-
-Buffer allocation has a very crude indefinite loop around waking the
-flusher threads and performing global NOFS direct reclaim because it can
-not handle allocation failures.
-
-The most immediate problem with this is that the allocation may fail due
-to a memory cgroup limit, where flushers + direct reclaim might not make
-any progress towards resolving the situation at all. Because unlike the
-global case, a memory cgroup may not have any cache at all, only
-anonymous pages but no swap. This situation will lead to a reclaim
-livelock with insane IO from waking the flushers and thrashing unrelated
-filesystem cache in a tight loop.
-
-Use __GFP_NOFAIL allocations for buffers for now. This makes sure that
-any looping happens in the page allocator, which knows how to
-orchestrate kswapd, direct reclaim, and the flushers sensibly. It also
-allows memory cgroups to detect allocations that can't handle failure
-and will allow them to ultimately bypass the limit if reclaim can not
-make progress.
-
-Reported-by: azurIt <azurit@pobox.sk>
-Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
-Cc: Michal Hocko <mhocko@suse.cz>
-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>
-
----
- fs/buffer.c | 14 ++++++++++++--
- mm/memcontrol.c | 2 ++
- 2 files changed, 14 insertions(+), 2 deletions(-)
-
---- a/fs/buffer.c
-+++ b/fs/buffer.c
-@@ -957,9 +957,19 @@ grow_dev_page(struct block_device *bdev,
- struct buffer_head *bh;
- sector_t end_block;
- int ret = 0; /* Will call free_more_memory() */
-+ gfp_t gfp_mask;
-
-- page = find_or_create_page(inode->i_mapping, index,
-- (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE);
-+ gfp_mask = mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS;
-+ gfp_mask |= __GFP_MOVABLE;
-+ /*
-+ * XXX: __getblk_slow() can not really deal with failure and
-+ * will endlessly loop on improvised global reclaim. Prefer
-+ * looping in the allocator rather than here, at least that
-+ * code knows what it's doing.
-+ */
-+ gfp_mask |= __GFP_NOFAIL;
-+
-+ page = find_or_create_page(inode->i_mapping, index, gfp_mask);
- if (!page)
- return ret;
-
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -2412,6 +2412,8 @@ done:
- return 0;
- nomem:
- *ptr = NULL;
-+ if (gfp_mask & __GFP_NOFAIL)
-+ return 0;
- return -ENOMEM;
- bypass:
- *ptr = root_mem_cgroup;
+++ /dev/null
-From c3d16e16522fe3fe8759735850a0676da18f4b1d Mon Sep 17 00:00:00 2001
-From: Cyrill Gorcunov <gorcunov@gmail.com>
-Date: Wed, 16 Oct 2013 13:46:51 -0700
-Subject: mm: migration: do not lose soft dirty bit if page is in migration state
-
-From: Cyrill Gorcunov <gorcunov@gmail.com>
-
-commit c3d16e16522fe3fe8759735850a0676da18f4b1d upstream.
-
-If page migration is turned on in config and the page is migrating, we
-may lose the soft dirty bit. If fork and mprotect are called on
-migrating pages (once migration is complete) pages do not obtain the
-soft dirty bit in the correspond pte entries. Fix it adding an
-appropriate test on swap entries.
-
-Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
-Cc: Pavel Emelyanov <xemul@parallels.com>
-Cc: Andy Lutomirski <luto@amacapital.net>
-Cc: Matt Mackall <mpm@selenic.com>
-Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
-Cc: Marcelo Tosatti <mtosatti@redhat.com>
-Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
-Cc: Stephen Rothwell <sfr@canb.auug.org.au>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
-Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
-Cc: Mel Gorman <mel@csn.ul.ie>
-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/memory.c | 2 ++
- mm/migrate.c | 2 ++
- mm/mprotect.c | 7 +++++--
- 3 files changed, 9 insertions(+), 2 deletions(-)
-
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -876,6 +876,8 @@ copy_one_pte(struct mm_struct *dst_mm, s
- */
- make_migration_entry_read(&entry);
- pte = swp_entry_to_pte(entry);
-+ if (pte_swp_soft_dirty(*src_pte))
-+ pte = pte_swp_mksoft_dirty(pte);
- set_pte_at(src_mm, addr, src_pte, pte);
- }
- }
---- a/mm/migrate.c
-+++ b/mm/migrate.c
-@@ -139,6 +139,8 @@ static int remove_migration_pte(struct p
-
- get_page(new);
- pte = pte_mkold(mk_pte(new, vma->vm_page_prot));
-+ if (pte_swp_soft_dirty(*ptep))
-+ pte = pte_mksoft_dirty(pte);
- if (is_write_migration_entry(entry))
- pte = pte_mkwrite(pte);
- #ifdef CONFIG_HUGETLB_PAGE
---- a/mm/mprotect.c
-+++ b/mm/mprotect.c
-@@ -64,13 +64,16 @@ static void change_pte_range(struct mm_s
- swp_entry_t entry = pte_to_swp_entry(oldpte);
-
- if (is_write_migration_entry(entry)) {
-+ pte_t newpte;
- /*
- * A protection check is difficult so
- * just be safe and disable write
- */
- make_migration_entry_read(&entry);
-- set_pte_at(mm, addr, pte,
-- swp_entry_to_pte(entry));
-+ newpte = swp_entry_to_pte(entry);
-+ if (pte_swp_soft_dirty(oldpte))
-+ newpte = pte_swp_mksoft_dirty(newpte);
-+ set_pte_at(mm, addr, pte, newpte);
- }
- }
- } while (pte++, addr += PAGE_SIZE, addr != end);