Re: [PATCH v3 05/16] mm/page_alloc: unify __alloc_frozen_pages[_nolock]_noprof()
From: Harry Yoo
Date: Tue Jun 30 2026 - 09:40:59 EST
On 6/29/26 10:11 PM, Brendan Jackman wrote:
> Currently the core allocator code is controlled by ALLOC_NOLOCK, but the
> main entry point function is significantly different from the normal
> __alloc_frozen_pages_nolock(), this is tiring when reading the code.
>
> Plumb the ALLOC_NOLOCK control one layer up in the call stack: create
> an alloc_flags argument to __alloc_frozen_pages_nolock() (which is only
> exposed to mm/) and then turn the nolock variant into a thin wrapper
> that just sets that flag (as well as handling NUMA_NO_NODE, similar to
> how some of the wrappers in gfp.h do).
>
> Rationale that this doesn't change anything:
>
> 1. Simple bits: A bunch of the nolock-specific handling is just moved to
> the new alloc_order_allowed(), alloc_trylock_allowed() and
> gfp_trylock.
Right.
> 2. __alloc_frozen_pages_noprof() has some extra logic that wasn't
> previously in the nolock variant:
>
> a. Application of gfp_allowed_mask; this only affects early boot, and
> only flags that affect the slowpath get changed here.
gfp_allowed_mask clears __GFP_RECLAIM, and that means now allocations
with GFP_KERNEL during early boot would see
gfpflags_allow_spinning() = false.
The helper is not used in in the page allocator, but used in
memcg/stackdepot/page_owner.
> b. Application of current_gfp_context() - also only affects the
> slowpath
PF_MEMALLOC_PIN affects the fast path, but ALLOC_NOLOCK users
won't be affected.
What about alloc_flags_nofragment/nonblocking()?
> 3. The slowpath itself: this is now just explicitly skipped under
> !ALLOC_TRYLOCK.
Right.
> Ulterior motive: adding an alloc_flags arg to the allocator's
> mm-internal entrypoint can later be used to do more allocation
> customisation without needing to create new GFP flags.
>
> While adding this flag to a bunch of places, create ALLOC_DEFAULT to
> avoid a mysterious literal 0 in most places.
>
> alloc_frozen_pages_noprof() is defined above the alloc flags
The function is defined below the alloc flags, no?
> so just leave that as a slightly messy
> exception instead of trying to fully reorder mm/internal.h for that one
> case.
>
> No functional change intended.
>
> Signed-off-by: Brendan Jackman <jackmanb@xxxxxxxxxx>
> ---
> mm/hugetlb.c | 3 +-
> mm/mempolicy.c | 10 ++--
> mm/page_alloc.c | 178 +++++++++++++++++++++++++++++---------------------------
> mm/page_alloc.h | 6 +-
> mm/slub.c | 6 +-
> 5 files changed, 108 insertions(+), 95 deletions(-)
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index a3ba63c7f9199..8d409d075e3e9 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -5271,24 +5271,98 @@ void free_pages_bulk(struct page **page_array, unsigned long nr_pages)
> }
> }
>
> +static inline bool alloc_trylock_allowed(void)
> +{
> + /*
> + * In PREEMPT_RT spin_trylock() will call raw_spin_lock() which is
> + * unsafe in NMI. If spin_trylock() is called from hard IRQ the current
> + * task may be waiting for one rt_spin_lock, but rt_spin_trylock() will
> + * mark the task as the owner of another rt_spin_lock which will
> + * confuse PI logic, so return immediately if called from hard IRQ or
> + * NMI.
> + *
> + * Note, irqs_disabled() case is ok. This function can be called
> + * from raw_spin_lock_irqsave region.
> + */
> + if (IS_ENABLED(CONFIG_PREEMPT_RT) && (in_nmi() || in_hardirq()))
> + return false;
> +
> + /* On UP, spin_trylock() always succeeds even when it is locked */
> + if (!IS_ENABLED(CONFIG_SMP) && in_nmi())
> + return false;
Except for deferred_pages_enabled(), it's not specific to the page
allocator. SLUB has
/*
* See the comment for the same check in
* alloc_frozen_pages_nolock_noprof()
*/
... and repeats the same thing as above.
Perhaps let's factor it out into a helper
rather than trying not to forget to update the other place?
> + /* Bailout, since _deferred_grow_zone() needs to take a lock */
> + if (deferred_pages_enabled())
> + return false;
> +
> + return true;
> +}
--
Cheers,
Harry / Hyeonggon
Attachment:
OpenPGP_signature.asc
Description: OpenPGP digital signature