Re: [PATCH v7 01/13] memory-failure: Fix hardware poison check in unpoison_memory() again
[email protected] Thu, 30 Jul 2026 22:39:57 -0700
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.stable,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
On 7/28/2026 1:43 PM, Matthew Wilcox (Oracle) wrote:
> The earlier patch (6c54312f9689) that attempted to fix unpoison_memory()
> was incorrect for hugetlb folios. Before a6fddef49eef, we checked the
> head page for poison (which was correct for hugetlb and incorrect for
> THP). We are currently incapable
>
>
> The earlier patch (6c54312f9689) that attempted to fix unpoison_memory()
> was incorrect for hugetlb folios. Before a6fddef49eef, we checked
> the head page for poison (which was correct for hugetlb and incorrect
> for THP). We are currently incapable of unpoisoning pages (other than
> the first page) in a hugetlb folio.
>
> Use is_page_hwpoison() which handles hugetlb pages sufficiently well for
> this purpose. This is racy as we don't have a reference on the folio at
> this point, but fixing that properly requires deeper surgery and this
> is a CAP_SYS_ADMIN path only so this will do for the moment and can be
> easily backported. It's no worse than the situation before a6fddef49eef.
>
> The other bug in a6fddef49eef is that we currently clear the HWPoison
> flag on the precise page, which is wrong for hugetlb. Fix that too.
>
> Fixes: a6fddef49eef ("mm/memory-failure: convert unpoison_memory() to folios")
> Cc: [email protected]
> Cc: Miaohe Lin <[email protected]>
> Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
> ---
> mm/memory-failure.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index 51508a55c405..944e6e1d4971 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -2695,8 +2695,8 @@ int unpoison_memory(unsigned long pfn)
> goto unlock_mutex;
> }
>
> - if (!PageHWPoison(p)) {
> - unpoison_pr_info("%#lx: page was already unpoisoned\n",
> + if (!is_page_hwpoison(p)) {
> + unpoison_pr_info("%#lx: page is not poisoned\n",
> pfn, &unpoison_rs);
> goto unlock_mutex;
> }
> @@ -2748,6 +2748,7 @@ int unpoison_memory(unsigned long pfn)
> folio_put(folio);
> goto unlock_mutex;
> }
> + p = &folio->page;
> }
>
> folio_put(folio);
> --
> 2.47.3
>
I think I spot another pre-existing issue in unpoison_memory():
the XXX line doesn't work for non-hugetlb free large folio because it'll
just try to clear PG_hwpoison in the folio->page, not the precise 'pfn'
page. Something like below could do.
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 51508a55c405..14915718ace5 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -2730,8 +2730,10 @@ int unpoison_memory(unsigned long pfn)
count = folio_free_raw_hwp(folio, false);
if (count == 0)
goto unlock_mutex;
+ else
+ ret = folio_test_clear_hwpoison(folio) ?
0 : -EBUSY;
}
- ret = folio_test_clear_hwpoison(folio) ? 0 : -EBUSY;
<--- XXX
+ ret = TestClearPageHWPoison(p) ? 0 : -EBUSY;
} else if (ghp < 0) {
if (ghp == -EHWPOISON) {
ret = put_page_back_buddy(p) ? 0 : -EBUSY;
thanks,
-jane