]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0022-mm-shmem-do-not-wait-for-lock_page-in-shmem_unused_h.patch
update sources to Ubuntu-4.13.0-45.50
[pve-kernel.git] / patches / kernel / 0022-mm-shmem-do-not-wait-for-lock_page-in-shmem_unused_h.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
3 Date: Fri, 23 Mar 2018 09:19:21 +0100
4 Subject: [PATCH] mm/shmem: do not wait for lock_page() in
5 shmem_unused_huge_shrink()
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 shmem_unused_huge_shrink() gets called from reclaim path. Waiting for
11 page lock may lead to deadlock there.
12
13 There was a bug report that may be attributed to this:
14
15 http://lkml.kernel.org/r/alpine.LRH.2.11.1801242349220.30642@mail.ewheeler.net
16
17 Replace lock_page() with trylock_page() and skip the page if we failed to
18 lock it. We will get to the page on the next scan.
19
20 We can test for the PageTransHuge() outside the page lock as we only need
21 protection against splitting the page under us. Holding pin oni the page
22 is enough for this.
23
24 Link: http://lkml.kernel.org/r/20180316210830.43738-1-kirill.shutemov@linux.intel.com
25 Fixes: 779750d20b93 ("shmem: split huge pages beyond i_size under memory pressure")
26 Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
27 Reported-by: Eric Wheeler <linux-mm@lists.ewheeler.net>
28 Acked-by: Michal Hocko <mhocko@suse.com>
29 Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
30 Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
31 Cc: Hugh Dickins <hughd@google.com>
32 Cc: <stable@vger.kernel.org> [4.8+]
33 Signed-off-by: Andrew Morton <>
34 (cherry-picked from https://git.kernel.org/pub/scm/linux/kernel/git/mhocko/mm.git/commit/?h=since-4.15&id=73eccc61c701ee7b4223aea2079542a712feeea7)
35 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
36 ---
37 mm/shmem.c | 31 ++++++++++++++++++++-----------
38 1 file changed, 20 insertions(+), 11 deletions(-)
39
40 diff --git a/mm/shmem.c b/mm/shmem.c
41 index 859e4c224b80..2aae929eb90b 100644
42 --- a/mm/shmem.c
43 +++ b/mm/shmem.c
44 @@ -483,36 +483,45 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo,
45 info = list_entry(pos, struct shmem_inode_info, shrinklist);
46 inode = &info->vfs_inode;
47
48 - if (nr_to_split && split >= nr_to_split) {
49 - iput(inode);
50 - continue;
51 - }
52 + if (nr_to_split && split >= nr_to_split)
53 + goto leave;
54
55 - page = find_lock_page(inode->i_mapping,
56 + page = find_get_page(inode->i_mapping,
57 (inode->i_size & HPAGE_PMD_MASK) >> PAGE_SHIFT);
58 if (!page)
59 goto drop;
60
61 + /* No huge page at the end of the file: nothing to split */
62 if (!PageTransHuge(page)) {
63 - unlock_page(page);
64 put_page(page);
65 goto drop;
66 }
67
68 + /*
69 + * Leave the inode on the list if we failed to lock
70 + * the page at this time.
71 + *
72 + * Waiting for the lock may lead to deadlock in the
73 + * reclaim path.
74 + */
75 + if (!trylock_page(page)) {
76 + put_page(page);
77 + goto leave;
78 + }
79 +
80 ret = split_huge_page(page);
81 unlock_page(page);
82 put_page(page);
83
84 - if (ret) {
85 - /* split failed: leave it on the list */
86 - iput(inode);
87 - continue;
88 - }
89 + /* If split failed leave the inode on the list */
90 + if (ret)
91 + goto leave;
92
93 split++;
94 drop:
95 list_del_init(&info->shrinklist);
96 removed++;
97 +leave:
98 iput(inode);
99 }
100
101 --
102 2.14.2
103