mm, hwpoison: kill procs if unmap fails
authorMiaohe Lin <linmiaohe@huawei.com>
Thu, 18 Aug 2022 13:00:15 +0000 (21:00 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 12 Sep 2022 03:25:57 +0000 (20:25 -0700)
If try_to_unmap() fails, the hwpoisoned page still resides in the address
space of some processes.  We should kill these processes or the hwpoisoned
page might be consumed later.  collect_procs() is always called to collect
relevant processes now so they can be killed later if unmap fails.

[linmiaohe@huawei.com: v2]
Link: https://lkml.kernel.org/r/20220823032346.4260-6-linmiaohe@huawei.com
Link: https://lkml.kernel.org/r/20220818130016.45313-6-linmiaohe@huawei.com
Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
Acked-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/memory-failure.c

index 208a0f8..3b8e793 100644 (file)
@@ -1397,7 +1397,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
        struct address_space *mapping;
        LIST_HEAD(tokill);
        bool unmap_success;
-       int kill = 1, forcekill;
+       int forcekill;
        bool mlocked = PageMlocked(hpage);
 
        /*
@@ -1438,7 +1438,6 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
                if (page_mkclean(hpage)) {
                        SetPageDirty(hpage);
                } else {
-                       kill = 0;
                        ttu |= TTU_IGNORE_HWPOISON;
                        pr_info("%#lx: corrupted page was clean: dropped without side effects\n",
                                pfn);
@@ -1449,12 +1448,8 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
         * First collect all the processes that have the page
         * mapped in dirty form.  This has to be done before try_to_unmap,
         * because ttu takes the rmap data structures down.
-        *
-        * Error handling: We ignore errors here because
-        * there's nothing that can be done.
         */
-       if (kill)
-               collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED);
+       collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED);
 
        if (PageHuge(hpage) && !PageAnon(hpage)) {
                /*
@@ -1496,7 +1491,8 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
         * use a more force-full uncatchable kill to prevent
         * any accesses to the poisoned memory.
         */
-       forcekill = PageDirty(hpage) || (flags & MF_MUST_KILL);
+       forcekill = PageDirty(hpage) || (flags & MF_MUST_KILL) ||
+                   !unmap_success;
        kill_procs(&tokill, forcekill, !unmap_success, pfn, flags);
 
        return unmap_success;