From 5a7ad156fa48de86c16a07dacb4dcd77439576d6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fabian=20Gr=C3=BCnbichler?= Date: Mon, 26 Mar 2018 14:42:38 +0200 Subject: [PATCH] fix #1633: potential deadlock with THPs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit see https://marc.info/?l=linux-mm&m=151683828707588 Signed-off-by: Fabian Grünbichler --- ...it-for-lock_page-in-deferred_split_s.patch | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 patches/kernel/0022-mm-thp-Do-not-wait-for-lock_page-in-deferred_split_s.patch diff --git a/patches/kernel/0022-mm-thp-Do-not-wait-for-lock_page-in-deferred_split_s.patch b/patches/kernel/0022-mm-thp-Do-not-wait-for-lock_page-in-deferred_split_s.patch new file mode 100644 index 0000000..239aa42 --- /dev/null +++ b/patches/kernel/0022-mm-thp-Do-not-wait-for-lock_page-in-deferred_split_s.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Thu, 15 Mar 2018 18:07:47 +0300 +Subject: [PATCH] mm/thp: Do not wait for lock_page() in deferred_split_scan() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +deferred_split_scan() gets called from reclaim path. Waiting for page +lock may lead to deadlock there. + +Replace lock_page() with trylock_page() and skip the page if we failed +to lock it. We will get to the page on the next scan. + +Fixes: 9a982250f773 ("thp: introduce deferred_split_huge_page()") + +Signed-off-by: Kirill A. Shutemov +Acked-by: Michal Hocko +(cherry-picked from https://patchwork.kernel.org/patch/10284703/) +Signed-off-by: Fabian Grünbichler +--- + mm/huge_memory.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 8b887db33383..5c4093e0be8d 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -2621,11 +2621,13 @@ static unsigned long deferred_split_scan(struct shrinker *shrink, + + list_for_each_safe(pos, next, &list) { + page = list_entry((void *)pos, struct page, mapping); +- lock_page(page); ++ if (!trylock_page(page)) ++ goto next; + /* split_huge_page() removes page from list on success */ + if (!split_huge_page(page)) + split++; + unlock_page(page); ++next: + put_page(page); + } + +-- +2.14.2 + -- 2.39.5