aboutsummaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorKevin Hilman <khilman@linaro.org>2015-09-14 14:22:30 -0700
committerKevin Hilman <khilman@linaro.org>2015-09-14 14:22:30 -0700
commita143f427f3e7c6d80bc1d288334706a1f8237f5f (patch)
tree59e96413cf2013afb70bfaaca5f89937d9d7ac20 /mm
parentd9e292d3ea94ab21f028108527a908e415e856ef (diff)
parentf249a14dd1b6b341e7b5e29b64c0edae6e13b7f5 (diff)
Merge branch 'linux-linaro-lsk-v4.1' into linux-linaro-lsk-v4.1-rtlsk-v4.1-15.11-rtlsk-v4.1-15.10-rtlsk-v4.1-15.09-rt
Diffstat (limited to 'mm')
-rw-r--r--mm/memory-failure.c15
-rw-r--r--mm/vmscan.c14
2 files changed, 13 insertions, 16 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 501820c815b3..9f48145c884f 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1558,6 +1558,8 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags)
*/
ret = __get_any_page(page, pfn, 0);
if (!PageLRU(page)) {
+ /* Drop page reference which is from __get_any_page() */
+ put_page(page);
pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n",
pfn, page->flags);
return -EIO;
@@ -1587,13 +1589,12 @@ static int soft_offline_huge_page(struct page *page, int flags)
unlock_page(hpage);
ret = isolate_huge_page(hpage, &pagelist);
- if (ret) {
- /*
- * get_any_page() and isolate_huge_page() takes a refcount each,
- * so need to drop one here.
- */
- put_page(hpage);
- } else {
+ /*
+ * get_any_page() and isolate_huge_page() takes a refcount each,
+ * so need to drop one here.
+ */
+ put_page(hpage);
+ if (!ret) {
pr_info("soft offline: %#lx hugepage failed to isolate\n", pfn);
return -EBUSY;
}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 5e8eadd71bac..0d024fc8aa8e 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -937,21 +937,17 @@ static unsigned long shrink_page_list(struct list_head *page_list,
*
* 2) Global reclaim encounters a page, memcg encounters a
* page that is not marked for immediate reclaim or
- * the caller does not have __GFP_IO. In this case mark
+ * the caller does not have __GFP_FS (or __GFP_IO if it's
+ * simply going to swap, not to fs). In this case mark
* the page for immediate reclaim and continue scanning.
*
- * __GFP_IO is checked because a loop driver thread might
+ * Require may_enter_fs because we would wait on fs, which
+ * may not have submitted IO yet. And the loop driver might
* enter reclaim, and deadlock if it waits on a page for
* which it is needed to do the write (loop masks off
* __GFP_IO|__GFP_FS for this reason); but more thought
* would probably show more reasons.
*
- * Don't require __GFP_FS, since we're not going into the
- * FS, just waiting on its writeback completion. Worryingly,
- * ext4 gfs2 and xfs allocate pages with
- * grab_cache_page_write_begin(,,AOP_FLAG_NOFS), so testing
- * may_enter_fs here is liable to OOM on them.
- *
* 3) memcg encounters a page that is not already marked
* PageReclaim. memcg does not have any dirty pages
* throttling so we could easily OOM just because too many
@@ -968,7 +964,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
/* Case 2 above */
} else if (global_reclaim(sc) ||
- !PageReclaim(page) || !(sc->gfp_mask & __GFP_IO)) {
+ !PageReclaim(page) || !may_enter_fs) {
/*
* This is slightly racy - end_page_writeback()
* might have just cleared PageReclaim, then