From 8e89f13c598e1dc0f62163f745de93cba31ca548 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fabian=20Gr=C3=BCnbichler?= Date: Mon, 26 Mar 2018 14:42:39 +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/0007-mm-thp-Do-not-wait-for-lock_page-in-deferred_split_s.patch diff --git a/patches/kernel/0007-mm-thp-Do-not-wait-for-lock_page-in-deferred_split_s.patch b/patches/kernel/0007-mm-thp-Do-not-wait-for-lock_page-in-deferred_split_s.patch new file mode 100644 index 0000000..9497533 --- /dev/null +++ b/patches/kernel/0007-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 0e7ded98d114..4ed6c89e95c3 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -2791,11 +2791,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.2