* [PATCH] mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio
@ 2026-10-28 15:43 Mani Tofigh via B4 Relay
2026-10-29 15:43 ` sashiko-bot
0 siblings, 1 reply; 3+ messages in thread
From: Mani Tofigh via B4 Relay @ 2026-10-28 15:43 UTC (permalink / raw)
To: Muchun Song, Oscar Salvador, David Hildenbrand, Miaohe Lin,
Andrew Morton
Cc: Naoya Horiguchi, Matthew Wilcox, Jane Chu, linux-mm, linux-kernel,
tz2294, stable, Mani Tofigh
From: Mani Tofigh <mt4022@columbia.edu>
If hugetlb_update_hwpoison() fails to allocate a raw_hwp_page, the folio
is marked raw_hwp_unreliable and __update_and_free_hugetlb_folio() leaks
it intentionally. With hugetlb_free_vmemmap=on, it's leaked before the
hugetlb flag is cleared, since commit 32c877191e02 ("hugetlb: do not
clear hugetlb dtor until allocating vmemmap") doesn't remove the flag
until the vmemmap is restored. The leaked folio is then a hugetlb folio
with refcount 0 and on no list (the same state as a hugetlb folio that
is being freed), but nothing is freeing it, and
dissolve_free_hugetlb_folio() keeps retrying on it. Offlining its
memory block then never completes:
[ 3.271255] Memory failure: 0x20007: recovery action for free huge page: Failed
[ 41.729695] INFO: task hugeoffline:77 blocked for more than 20 seconds.
...
[ 41.733014] get_online_mems+0xc1/0xd0
[ 41.733026] soft_offline_page+0xfd/0x9b0
alloc_and_dissolve_hugetlb_folio() loops on it the same way.
Check raw_hwp_unreliable after the hugetlb flag is cleared so that the
folio is leaked as a non-hugetlb folio, as without vmemmap
optimization. With the fix, no task hangs.
This bug was identified and confirmed with the help of fault-injection
testing on a deterministic hypervisor currently under development. The
C reproducer below however chains the specific events that trigger it.
Fixes: 32c877191e02 ("hugetlb: do not clear hugetlb dtor until allocating vmemmap")
Cc: stable@vger.kernel.org
Signed-off-by: Mani Tofigh <mt4022@columbia.edu>
---
This changes the same lines as patch 07/15 of Matthew's "Use
generic_file_read_iter() in hugetlbfs" series [1]. On top of that
series, the check goes right after the folio_clear_hugetlb() call.
[1] https://lore.kernel.org/all/20260805210557.1118966-8-willy@infradead.org/
Reproducer: https://github.com/manitofigh/files/blob/main/linux-repros/hugeoffline.c
---
mm/hugetlb.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 4a008afaedf9..4d6b7ab49502 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1472,13 +1472,6 @@ static void __update_and_free_hugetlb_folio(struct hstate *h,
return;
}
- /*
- * If we don't know which subpages are hwpoisoned, we can't free
- * the hugepage, so it's leaked intentionally.
- */
- if (folio_test_hugetlb_raw_hwp_unreliable(folio))
- return;
-
/*
* If folio is not vmemmap optimized (!clear_flag), then the folio
* is no longer identified as a hugetlb page. hugetlb_vmemmap_restore_folio
@@ -1506,6 +1499,14 @@ static void __update_and_free_hugetlb_folio(struct hstate *h,
spin_unlock_irq(&hugetlb_lock);
}
+ /*
+ * If we don't know which subpages are hwpoisoned, we can't free
+ * the hugepage, so it's leaked intentionally, but only once it is
+ * no longer a hugetlb folio.
+ */
+ if (folio_test_hugetlb_raw_hwp_unreliable(folio))
+ return;
+
/*
* Move PageHWPoison flag from head page to the raw error pages,
* which makes any healthy subpages reusable.
---
base-commit: bae9a042b03b27924c6fd5bdc00a20d6a44d6041
change-id: 20261028-hugetlb-hwpoison-leak-b8d344361413
Best regards,
--
Mani Tofigh <mt4022@columbia.edu>
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio
2026-10-28 15:43 [PATCH] mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio Mani Tofigh via B4 Relay
@ 2026-10-29 15:43 ` sashiko-bot
2026-10-29 17:56 ` Mani Tofigh
0 siblings, 1 reply; 3+ messages in thread
From: sashiko-bot @ 2026-10-29 15:43 UTC (permalink / raw)
To: Mani Tofigh, Muchun Song, Oscar Salvador, David Hildenbrand,
Miaohe Lin, Andrew Morton
Cc: Naoya Horiguchi, Matthew Wilcox, Jane Chu, linux-mm, tz2294
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] mm/hugetlb: add_hugetlb_folio() clears HPG_raw_hwp_unreliable on error
--
commit cae6d1104a254ddb073fab05f2a9308005af88fa
Author: Mani Tofigh <mt4022@columbia.edu>
mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio
This commit moves the folio_test_hugetlb_raw_hwp_unreliable() check in
__update_and_free_hugetlb_folio() to after the hugetlb flag is cleared, so
that vmemmap-optimized folios with unreliable hwpoison tracking are leaked as
non-hugetlb folios instead of causing dissolve paths to loop indefinitely.
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 4a008afaedf95..4d6b7ab49502f 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1472,13 +1472,6 @@ static void __update_and_free_hugetlb_folio(struct hstate *h,
> return;
> }
>
> - /*
> - * If we don't know which subpages are hwpoisoned, we can't free
> - * the hugepage, so it's leaked intentionally.
> - */
> - if (folio_test_hugetlb_raw_hwp_unreliable(folio))
> - return;
> -
> /*
> * If folio is not vmemmap optimized (!clear_flag), then the folio
> * is no longer identified as a hugetlb page. hugetlb_vmemmap_restore_folio
> @@ -1506,6 +1499,14 @@ static void __update_and_free_hugetlb_folio(struct hstate *h,
> spin_unlock_irq(&hugetlb_lock);
> }
>
> + /*
> + * If we don't know which subpages are hwpoisoned, we can't free
> + * the hugepage, so it's leaked intentionally, but only once it is
> + * no longer a hugetlb folio.
> + */
> + if (folio_test_hugetlb_raw_hwp_unreliable(folio))
> + return;
[Severity: Critical]
Can moving folio_test_hugetlb_raw_hwp_unreliable() below
hugetlb_vmemmap_restore_folio() cause hardware-poisoned subpages to be freed
back to the buddy allocator as healthy pages if vmemmap restoration fails?
When hugetlb_update_hwpoison() fails to allocate a raw_hwp_page struct, it
marks the folio with HPG_raw_hwp_unreliable and frees the raw_hwp_page list
without transferring PG_hwpoison to the subpages:
mm/memory-failure.c:hugetlb_update_hwpoison() {
...
folio_set_hugetlb_raw_hwp_unreliable(folio);
/*
* Once hugetlb_raw_hwp_unreliable is set, raw_hwp_page is not
* used any more, so free it.
*/
__folio_free_raw_hwp(folio, false);
...
}
With this change, __update_and_free_hugetlb_folio() now calls
hugetlb_vmemmap_restore_folio() on a raw_hwp_unreliable folio before checking
the flag. If hugetlb_vmemmap_restore_folio() fails to allocate vmemmap pages,
the error path puts the folio back on the hugetlb freelist via
add_hugetlb_folio():
mm/hugetlb.c:__update_and_free_hugetlb_folio() {
...
if (clear_flag && hugetlb_vmemmap_restore_folio(h, folio)) {
spin_lock_irq(&hugetlb_lock);
add_hugetlb_folio(h, folio, true);
spin_unlock_irq(&hugetlb_lock);
return;
}
...
}
However, add_hugetlb_folio() zeroes folio->private and only restores
HPG_vmemmap_optimized, which clears HPG_raw_hwp_unreliable (as well as
HPG_cma):
mm/hugetlb.c:add_hugetlb_folio() {
...
__folio_set_hugetlb(folio);
/* Clear all folio->private flags except hugetlb_vmemmap_optimized. */
folio->private = NULL;
folio_set_hugetlb_vmemmap_optimized(folio);
...
}
If the folio is later freed or dissolved and hugetlb_vmemmap_restore_folio()
succeeds, folio_test_hugetlb_raw_hwp_unreliable(folio) will now return false.
Wouldn't __update_and_free_hugetlb_folio() then call
folio_clear_hugetlb_hwpoison(), clearing PG_hwpoison on the head page against
an empty raw_hwp_page list, and release the poisoned subpages to
free_frozen_pages() as clean pages?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-hugetlb-hwpoison-leak-v1-1-77ce56002523@columbia.edu?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio
2026-10-29 15:43 ` sashiko-bot
@ 2026-10-29 17:56 ` Mani Tofigh
0 siblings, 0 replies; 3+ messages in thread
From: Mani Tofigh @ 2026-10-29 17:56 UTC (permalink / raw)
To: sashiko-reviews, Muchun Song, Oscar Salvador, David Hildenbrand,
Miaohe Lin, Andrew Morton
Cc: Naoya Horiguchi, Matthew Wilcox, Jane Chu, linux-mm, tz2294,
Zi Yan, kaitao.cheng
+Cc Zi, Kaitao
On 10/29/26 11:43 AM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Critical] mm/hugetlb: add_hugetlb_folio() clears HPG_raw_hwp_unreliable on error
> --
>
> commit cae6d1104a254ddb073fab05f2a9308005af88fa
> Author: Mani Tofigh <mt4022@columbia.edu>
>
> mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio
>
> This commit moves the folio_test_hugetlb_raw_hwp_unreliable() check in
> __update_and_free_hugetlb_folio() to after the hugetlb flag is cleared, so
> that vmemmap-optimized folios with unreliable hwpoison tracking are leaked as
> non-hugetlb folios instead of causing dissolve paths to loop indefinitely.
>
> [Severity: Critical]
> Can moving folio_test_hugetlb_raw_hwp_unreliable() below
> hugetlb_vmemmap_restore_folio() cause hardware-poisoned subpages to be freed
> back to the buddy allocator as healthy pages if vmemmap restoration fails?
>
> When hugetlb_update_hwpoison() fails to allocate a raw_hwp_page struct, it
> marks the folio with HPG_raw_hwp_unreliable and frees the raw_hwp_page list
> without transferring PG_hwpoison to the subpages:
>
> If the folio is later freed or dissolved and hugetlb_vmemmap_restore_folio()
> succeeds, folio_test_hugetlb_raw_hwp_unreliable(folio) will now return false.
> Wouldn't __update_and_free_hugetlb_folio() then call
> folio_clear_hugetlb_hwpoison(), clearing PG_hwpoison on the head page against
> an empty raw_hwp_page list, and release the poisoned subpages to
> free_frozen_pages() as clean pages?
>
This isn't something new with this patch. dissolve_free_hugetlb_folio()
already drops raw_hwp_unreliable the same way when the vmemmap restore
fails. Zi's change [1] to stop clearing folio->private in
add_hugetlb_folio() would address this so I think this patch can rely
on it too.
[1]
https://lore.kernel.org/linux-mm/A1A14368-7A43-40ED-B2AB-C2EC2C5FFB1D@linux.dev/
Mani
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-29 17:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-28 15:43 [PATCH] mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio Mani Tofigh via B4 Relay
2026-10-29 15:43 ` sashiko-bot
2026-10-29 17:56 ` Mani Tofigh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox