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