]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.11.2/mm-prevent-potential-recursive-reclaim-due-to-clearing-pf_memalloc.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.11.2 / mm-prevent-potential-recursive-reclaim-due-to-clearing-pf_memalloc.patch
CommitLineData
5032628c
GKH
1From 62be1511b1db8066220b18b7d4da2e6b9fdc69fb Mon Sep 17 00:00:00 2001
2From: Vlastimil Babka <vbabka@suse.cz>
3Date: Mon, 8 May 2017 15:59:46 -0700
4Subject: mm: prevent potential recursive reclaim due to clearing PF_MEMALLOC
5
6From: Vlastimil Babka <vbabka@suse.cz>
7
8commit 62be1511b1db8066220b18b7d4da2e6b9fdc69fb upstream.
9
10Patch series "more robust PF_MEMALLOC handling"
11
12This series aims to unify the setting and clearing of PF_MEMALLOC, which
13prevents recursive reclaim. There are some places that clear the flag
14unconditionally from current->flags, which may result in clearing a
15pre-existing flag. This already resulted in a bug report that Patch 1
16fixes (without the new helpers, to make backporting easier). Patch 2
17introduces the new helpers, modelled after existing memalloc_noio_* and
18memalloc_nofs_* helpers, and converts mm core to use them. Patches 3
19and 4 convert non-mm code.
20
21This patch (of 4):
22
23__alloc_pages_direct_compact() sets PF_MEMALLOC to prevent deadlock
24during page migration by lock_page() (see the comment in
25__unmap_and_move()). Then it unconditionally clears the flag, which can
26clear a pre-existing PF_MEMALLOC flag and result in recursive reclaim.
27This was not a problem until commit a8161d1ed609 ("mm, page_alloc:
28restructure direct compaction handling in slowpath"), because direct
29compation was called only after direct reclaim, which was skipped when
30PF_MEMALLOC flag was set.
31
32Even now it's only a theoretical issue, as the new callsite of
33__alloc_pages_direct_compact() is reached only for costly orders and
34when gfp_pfmemalloc_allowed() is true, which means either
35__GFP_NOMEMALLOC is in gfp_flags or in_interrupt() is true. There is no
36such known context, but let's play it safe and make
37__alloc_pages_direct_compact() robust for cases where PF_MEMALLOC is
38already set.
39
40Fixes: a8161d1ed609 ("mm, page_alloc: restructure direct compaction handling in slowpath")
41Link: http://lkml.kernel.org/r/20170405074700.29871-2-vbabka@suse.cz
42Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
43Reported-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
44Acked-by: Michal Hocko <mhocko@suse.com>
45Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
46Cc: Mel Gorman <mgorman@techsingularity.net>
47Cc: Johannes Weiner <hannes@cmpxchg.org>
48Cc: Boris Brezillon <boris.brezillon@free-electrons.com>
49Cc: Chris Leech <cleech@redhat.com>
50Cc: "David S. Miller" <davem@davemloft.net>
51Cc: Eric Dumazet <edumazet@google.com>
52Cc: Josef Bacik <jbacik@fb.com>
53Cc: Lee Duncan <lduncan@suse.com>
54Cc: Michal Hocko <mhocko@suse.com>
55Cc: Richard Weinberger <richard@nod.at>
56Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
57Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
58Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
59
60---
61 mm/page_alloc.c | 3 ++-
62 1 file changed, 2 insertions(+), 1 deletion(-)
63
64--- a/mm/page_alloc.c
65+++ b/mm/page_alloc.c
66@@ -3245,6 +3245,7 @@ __alloc_pages_direct_compact(gfp_t gfp_m
67 enum compact_priority prio, enum compact_result *compact_result)
68 {
69 struct page *page;
70+ unsigned int noreclaim_flag = current->flags & PF_MEMALLOC;
71
72 if (!order)
73 return NULL;
74@@ -3252,7 +3253,7 @@ __alloc_pages_direct_compact(gfp_t gfp_m
75 current->flags |= PF_MEMALLOC;
76 *compact_result = try_to_compact_pages(gfp_mask, order, alloc_flags, ac,
77 prio);
78- current->flags &= ~PF_MEMALLOC;
79+ current->flags = (current->flags & ~PF_MEMALLOC) | noreclaim_flag;
80
81 if (*compact_result <= COMPACT_INACTIVE)
82 return NULL;