Re: FAILED: patch "[PATCH] mm/huge_memory: separate out" failed to apply to 5.10-stable tree

"Lorenzo Stoakes (ARM)" <[email protected]>
Newsgroups org.kernel.vger.stable
Message-ID <aoMHsUr2PuKVixmi@lucifer>
On Mon, Aug 17, 2026 at 02:40:37PM +0200, [email protected] wrote:
>
> The patch below does not apply to the 5.10-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <[email protected]>.

Hi Greg,

Sorry about this this patch was mis-tagged and shouldn't be backported to any of
the kernel releases (it's not harmful, but there's no need to resolve conflicts
in any case).

It's a pure cleanup so is only necessary for tip.

Cheers, Lorenzo

>
> To reproduce the conflict and resubmit, you may use the following commands:
>
> git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
> git checkout FETCH_HEAD
> git cherry-pick -x 98bd3af0bb6bfdb0fb39cbfa05456acb374b691e
> # <resolve conflicts, build, test, etc.>
> git commit -s
> git send-email --to '<[email protected]>' --in-reply-to '2026081737-unleveled-prologue-7681@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
>
> Possible dependencies:
>
>
>
> thanks,
>
> greg k-h
>
> ------------------ original commit in Linus's tree ------------------
>
> From 98bd3af0bb6bfdb0fb39cbfa05456acb374b691e Mon Sep 17 00:00:00 2001
> From: "Lorenzo Stoakes (ARM)" <[email protected]>
> Date: Thu, 30 Jul 2026 11:55:48 +0100
> Subject: [PATCH] mm/huge_memory: separate out
>  CONFIG_PERSISTENT_HUGE_ZERO_FOLIO logic
>
> Rather than mixing the refcounted and non-refcounted
> CONFIG_PERSISTENT_HUGE_ZERO_FOLIO logic, separate the two out cleanly so
> it is clear what happens when this configuration option is set and what
> happens when it is not.
>
> Introduce HUGE_ZERO_UNSET_PFN to abstract the ~0UL assignment, only
> introduce the refcount, lock and shrinker if
> !CONFIG_PERSISTENT_HUGE_ZERO_FOLIO, abstract initialisation and teardown,
> abstract the huge zero folio allocation from refcounting.
>
> Also change a BUG_ON() to WARN_ON_ONCE() while we're at it.
>
> No functional change intended.
>
> Link: https://lore.kernel.org/[email protected]
> Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
> Fixes: 3b77e8c8cde5 ("mm/thp: make is_huge_zero_pmd() safe and quicker")
> Cc: Baolin Wang <[email protected]>
> Cc: Barry Song <[email protected]>
> Cc: David Hildenbrand (Arm) <[email protected]>
> Cc: Dev Jain <[email protected]>
> Cc: Hannes Reinecke <[email protected]>
> Cc: Hengbin Zhang <[email protected]>
> Cc: Hugh Dickins <[email protected]>
> Cc: Kiryl Shutsemau <[email protected]>
> Cc: Lance Yang <[email protected]>
> Cc: Liam R. Howlett <[email protected]>
> Cc: Nico Pache <[email protected]>
> Cc: Pankaj Raghav <[email protected]>
> Cc: Ryan Roberts <[email protected]>
> Cc: Yang Shi <[email protected]>
> Cc: Zi Yan <[email protected]>
> Cc: <[email protected]>
> Signed-off-by: Andrew Morton <[email protected]>
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index f43852ef9944..f84fe7913d88 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -78,10 +78,15 @@ static unsigned long deferred_split_scan(struct shrinker *shrink,
>  					 struct shrink_control *sc);
>  static bool split_underused_thp = true;
>
> +#define HUGE_ZERO_UNSET_PFN (~0UL)
> +struct folio *huge_zero_folio __read_mostly;
> +unsigned long huge_zero_pfn __read_mostly = HUGE_ZERO_UNSET_PFN;
> +#ifndef CONFIG_PERSISTENT_HUGE_ZERO_FOLIO
>  static atomic_t huge_zero_refcount;
>  static DEFINE_SPINLOCK(huge_zero_lock);
> -struct folio *huge_zero_folio __read_mostly;
> -unsigned long huge_zero_pfn __read_mostly = ~0UL;
> +static struct shrinker *huge_zero_folio_shrinker;
> +#endif
> +
>  unsigned long huge_anon_orders_always __read_mostly;
>  unsigned long huge_anon_orders_madvise __read_mostly;
>  unsigned long huge_anon_orders_inherit __read_mostly;
> @@ -223,6 +228,47 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
>  	return orders;
>  }
>
> +static struct folio *alloc_huge_zero_folio(void)
> +{
> +	struct folio *zero_folio;
> +
> +	zero_folio = folio_alloc((GFP_TRANSHUGE | __GFP_ZERO | __GFP_ZEROTAGS) &
> +				 ~__GFP_MOVABLE,
> +			HPAGE_PMD_ORDER);
> +	if (!zero_folio) {
> +		count_vm_event(THP_ZERO_PAGE_ALLOC_FAILED);
> +		return NULL;
> +	}
> +	folio_clear_large_rmappable(zero_folio); /* Explicitly not rmappable. */
> +	return zero_folio;
> +}
> +
> +#ifdef CONFIG_PERSISTENT_HUGE_ZERO_FOLIO
> +static int __init huge_zero_init(void)
> +{
> +	huge_zero_folio = alloc_huge_zero_folio();
> +	if (!huge_zero_folio) {
> +		pr_warn("Allocating persistent huge zero folio failed\n");
> +	} else {
> +		huge_zero_pfn = folio_pfn(huge_zero_folio);
> +		count_vm_event(THP_ZERO_PAGE_ALLOC);
> +	}
> +	return 0;
> +}
> +
> +static void __init huge_zero_shrinker_exit(void)
> +{
> +}
> +
> +struct folio *mm_get_huge_zero_folio(struct mm_struct *mm)
> +{
> +	return huge_zero_folio;
> +}
> +
> +void mm_put_huge_zero_folio(struct mm_struct *mm)
> +{
> +}
> +#else
>  static bool get_huge_zero_folio(void)
>  {
>  	struct folio *zero_folio;
> @@ -231,15 +277,9 @@ static bool get_huge_zero_folio(void)
>  	if (likely(atomic_inc_not_zero(&huge_zero_refcount)))
>  		return true;
>
> -	zero_folio = folio_alloc((GFP_TRANSHUGE | __GFP_ZERO | __GFP_ZEROTAGS) &
> -				 ~__GFP_MOVABLE,
> -			HPAGE_PMD_ORDER);
> -	if (!zero_folio) {
> -		count_vm_event(THP_ZERO_PAGE_ALLOC_FAILED);
> +	zero_folio = alloc_huge_zero_folio();
> +	if (unlikely(!zero_folio))
>  		return false;
> -	}
> -	/* Ensure zero folio won't have large_rmappable flag set. */
> -	folio_clear_large_rmappable(zero_folio);
>
>  	/* Paired with critical section in shrink_huge_zero_folio_scan(). */
>  	spin_lock(&huge_zero_lock);
> @@ -266,33 +306,7 @@ static void put_huge_zero_folio(void)
>  	 * Counter should never go to zero here. Only shrinker can put
>  	 * last reference.
>  	 */
> -	BUG_ON(atomic_dec_and_test(&huge_zero_refcount));
> -}
> -
> -struct folio *mm_get_huge_zero_folio(struct mm_struct *mm)
> -{
> -	if (IS_ENABLED(CONFIG_PERSISTENT_HUGE_ZERO_FOLIO))
> -		return huge_zero_folio;
> -
> -	if (mm_flags_test(MMF_HUGE_ZERO_FOLIO, mm))
> -		return READ_ONCE(huge_zero_folio);
> -
> -	if (!get_huge_zero_folio())
> -		return NULL;
> -
> -	if (mm_flags_test_and_set(MMF_HUGE_ZERO_FOLIO, mm))
> -		put_huge_zero_folio();
> -
> -	return READ_ONCE(huge_zero_folio);
> -}
> -
> -void mm_put_huge_zero_folio(struct mm_struct *mm)
> -{
> -	if (IS_ENABLED(CONFIG_PERSISTENT_HUGE_ZERO_FOLIO))
> -		return;
> -
> -	if (mm_flags_test(MMF_HUGE_ZERO_FOLIO, mm))
> -		put_huge_zero_folio();
> +	WARN_ON_ONCE(atomic_dec_and_test(&huge_zero_refcount));
>  }
>
>  static unsigned long shrink_huge_zero_folio_count(struct shrinker *shrink,
> @@ -316,14 +330,53 @@ static unsigned long shrink_huge_zero_folio_scan(struct shrinker *shrink,
>  		zero_folio = huge_zero_folio;
>  		VM_WARN_ON_ONCE(!zero_folio);
>  		WRITE_ONCE(huge_zero_folio, NULL);
> -		WRITE_ONCE(huge_zero_pfn, ~0UL);
> +		WRITE_ONCE(huge_zero_pfn, HUGE_ZERO_UNSET_PFN);
>  	}
>
>  	folio_put(zero_folio);
>  	return HPAGE_PMD_NR;
>  }
>
> -static struct shrinker *huge_zero_folio_shrinker;
> +static int __init huge_zero_init(void)
> +{
> +	huge_zero_folio_shrinker = shrinker_alloc(0, "thp-zero");
> +	if (!huge_zero_folio_shrinker) {
> +		shrinker_free(deferred_split_shrinker);
> +		list_lru_destroy(&deferred_split_lru);
> +		return -ENOMEM;
> +	}
> +
> +	huge_zero_folio_shrinker->count_objects = shrink_huge_zero_folio_count;
> +	huge_zero_folio_shrinker->scan_objects = shrink_huge_zero_folio_scan;
> +	shrinker_register(huge_zero_folio_shrinker);
> +	return 0;
> +}
> +
> +static void __init huge_zero_shrinker_exit(void)
> +{
> +	shrinker_free(huge_zero_folio_shrinker);
> +}
> +
> +struct folio *mm_get_huge_zero_folio(struct mm_struct *mm)
> +{
> +	if (mm_flags_test(MMF_HUGE_ZERO_FOLIO, mm))
> +		return READ_ONCE(huge_zero_folio);
> +
> +	if (!get_huge_zero_folio())
> +		return NULL;
> +
> +	if (mm_flags_test_and_set(MMF_HUGE_ZERO_FOLIO, mm))
> +		put_huge_zero_folio();
> +
> +	return READ_ONCE(huge_zero_folio);
> +}
> +
> +void mm_put_huge_zero_folio(struct mm_struct *mm)
> +{
> +	if (mm_flags_test(MMF_HUGE_ZERO_FOLIO, mm))
> +		put_huge_zero_folio();
> +}
> +#endif /* CONFIG_PERSISTENT_HUGE_ZERO_FOLIO */
>
>  #ifdef CONFIG_SYSFS
>  static ssize_t enabled_show(struct kobject *kobj,
> @@ -987,39 +1040,14 @@ static int __init thp_shrinker_init(void)
>  	deferred_split_shrinker->scan_objects = deferred_split_scan;
>  	shrinker_register(deferred_split_shrinker);
>
> -	if (IS_ENABLED(CONFIG_PERSISTENT_HUGE_ZERO_FOLIO)) {
> -		/*
> -		 * Bump the reference of the huge_zero_folio and do not
> -		 * initialize the shrinker.
> -		 *
> -		 * huge_zero_folio will always be NULL on failure. We assume
> -		 * that get_huge_zero_folio() will most likely not fail as
> -		 * thp_shrinker_init() is invoked early on during boot.
> -		 */
> -		if (!get_huge_zero_folio())
> -			pr_warn("Allocating persistent huge zero folio failed\n");
> -		return 0;
> -	}
> -
> -	huge_zero_folio_shrinker = shrinker_alloc(0, "thp-zero");
> -	if (!huge_zero_folio_shrinker) {
> -		shrinker_free(deferred_split_shrinker);
> -		list_lru_destroy(&deferred_split_lru);
> -		return -ENOMEM;
> -	}
> -
> -	huge_zero_folio_shrinker->count_objects = shrink_huge_zero_folio_count;
> -	huge_zero_folio_shrinker->scan_objects = shrink_huge_zero_folio_scan;
> -	shrinker_register(huge_zero_folio_shrinker);
> -
> -	return 0;
> +	return huge_zero_init();
>  }
>
>  static void __init thp_shrinker_exit(void)
>  {
> -	shrinker_free(huge_zero_folio_shrinker);
>  	shrinker_free(deferred_split_shrinker);
>  	list_lru_destroy(&deferred_split_lru);
> +	huge_zero_shrinker_exit();
>  }
>
>  static int __init hugepage_init(void)
>

--
Cheers, Lorenzo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.