Re: [PATCH v8 07/15] hugetlb: Move poison to pages before clearing hugetlb page type

[email protected] Mon, 3 Aug 2026 23:47:13 -0700
Newsgroups gmane.linux.file-systems,gmane.linux.kernel.mm
Message-ID <[email protected]>

On 7/31/2026 1:07 PM, Matthew Wilcox (Oracle) wrote:
> For is_page_hwpoison() to be reliable, we need to set the hwpoison flag=20
> on each page before clearing the hugetlb flag. Introduce=20
> folio_clear_hugetlb() to make this easier. This does not by itself make=20
> is_page_hwpoison() reliable; see subsequent
>=20
>=20
> For is_page_hwpoison() to be reliable, we need to set the hwpoison
> flag on each page before clearing the hugetlb flag.  Introduce
> folio_clear_hugetlb() to make this easier.  This does not by
> itself make is_page_hwpoison() reliable; see subsequent patches.
>=20
> Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
> Reviewed-by: Gregory Price (Meta) <[email protected]>
> Reviewed-by: Miaohe Lin <[email protected]>
> ---
>   mm/hugetlb.c | 31 ++++++++++++++++++-------------
>   1 file changed, 18 insertions(+), 13 deletions(-)
>=20
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index cc8d98399913..47403d02be88 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1381,6 +1381,18 @@ static struct folio *alloc_gigantic_frozen_folio(i=
nt order, gfp_t gfp_mask, int
>   }
>   #endif
>  =20
> +static void folio_clear_hugetlb(struct folio *folio)
> +{
> +	/*
> +	 * Move HWPoison flag to each error page
> +	 * which makes any healthy pages reusable.
> +	 */
> +	if (unlikely(folio_test_hwpoison(folio)))
> +		folio_clear_hugetlb_hwpoison(folio);
> +
> +	__folio_clear_hugetlb(folio);
> +}
> +
>   /*
>    * Remove hugetlb folio from lists.
>    * If vmemmap exists for the folio, clear the hugetlb flag so that the
> @@ -1419,7 +1431,7 @@ void remove_hugetlb_folio(struct hstate *h, struct =
folio *folio,
>   	 * to tail struct pages.
>   	 */
>   	if (!folio_test_hugetlb_vmemmap_optimized(folio))
> -		__folio_clear_hugetlb(folio);
> +		folio_clear_hugetlb(folio);
>  =20
>   	h->nr_huge_pages--;
>   	h->nr_huge_pages_node[nid]--;
> @@ -1493,17 +1505,10 @@ static void __update_and_free_hugetlb_folio(struc=
t hstate *h,
>   	 */
>   	if (folio_test_hugetlb(folio)) {
>   		spin_lock_irq(&hugetlb_lock);
> -		__folio_clear_hugetlb(folio);
> +		folio_clear_hugetlb(folio);
>   		spin_unlock_irq(&hugetlb_lock);
>   	}
>  =20
> -	/*
> -	 * Move PageHWPoison flag from head page to the raw error pages,
> -	 * which makes any healthy subpages reusable.
> -	 */
> -	if (unlikely(folio_test_hwpoison(folio)))
> -		folio_clear_hugetlb_hwpoison(folio);
> -
>   	VM_BUG_ON_FOLIO(folio_ref_count(folio), folio);
>   	if (folio_test_hugetlb_cma(folio))
>   		hugetlb_cma_free_frozen_folio(folio);
> @@ -1595,7 +1600,7 @@ static void bulk_vmemmap_restore_error(struct hstat=
e *h,
>   		list_for_each_entry_safe(folio, t_folio, non_hvo_folios, lru) {
>   			list_del(&folio->lru);
>   			spin_lock_irq(&hugetlb_lock);
> -			__folio_clear_hugetlb(folio);
> +			folio_clear_hugetlb(folio);
>   			spin_unlock_irq(&hugetlb_lock);
>   			update_and_free_hugetlb_folio(h, folio, false);
>   			cond_resched();
> @@ -1620,7 +1625,7 @@ static void bulk_vmemmap_restore_error(struct hstat=
e *h,
>   			} else {
>   				list_del(&folio->lru);
>   				spin_lock_irq(&hugetlb_lock);
> -				__folio_clear_hugetlb(folio);
> +				folio_clear_hugetlb(folio);
>   				spin_unlock_irq(&hugetlb_lock);
>   				update_and_free_hugetlb_folio(h, folio, false);
>   				cond_resched();
> @@ -1653,14 +1658,14 @@ static void update_and_free_pages_bulk(struct hst=
ate *h,
>   	 * should only be pages on the non_hvo_folios list.
>   	 * Do note that the non_hvo_folios list could be empty.
>   	 * Without HVO enabled, ret will be 0 and there is no need to call
> -	 * __folio_clear_hugetlb as this was done previously.
> +	 * folio_clear_hugetlb as this was done previously.
>   	 */
>   	VM_WARN_ON(!list_empty(folio_list));
>   	VM_WARN_ON(ret < 0);
>   	if (!list_empty(&non_hvo_folios) && ret) {
>   		spin_lock_irq(&hugetlb_lock);
>   		list_for_each_entry(folio, &non_hvo_folios, lru)
> -			__folio_clear_hugetlb(folio);
> +			folio_clear_hugetlb(folio);
>   		spin_unlock_irq(&hugetlb_lock);
>   	}
>  =20
> --=20
> 2.47.3
>=20

With the patch, we're dissolving the raw_hwp_list at the earliest=20
opportunity upon freeing hugetlb, looks fine to me.

Reviewed-by: Jane Chu <[email protected]>

thanks,
-jane