All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio
@ 2026-10-28 15:43 ` Mani Tofigh
  0 siblings, 0 replies; 4+ 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] 4+ messages in thread

* [PATCH] mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio
@ 2026-10-28 15:43 ` Mani Tofigh
  0 siblings, 0 replies; 4+ messages in thread
From: Mani Tofigh @ 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

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] 4+ messages in thread

* Re: [PATCH] mm/hugetlb: clear the hugetlb flag before leaking a hwpoisoned folio
  2026-10-28 15:43 ` Mani Tofigh
  (?)
@ 2026-10-29 15:43 ` sashiko-bot
  2026-10-29 17:56   ` Mani Tofigh
  -1 siblings, 1 reply; 4+ 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] 4+ 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; 4+ 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] 4+ messages in thread

end of thread, other threads:[~2026-10-29 17:57 UTC | newest]

Thread overview: 4+ 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-28 15:43 ` Mani Tofigh
2026-10-29 15:43 ` sashiko-bot
2026-10-29 17:56   ` Mani Tofigh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.