Re: [PATCH] mm/page_alloc: unify __alloc_frozen_pages[_nolock]_noprof()
From: Hao Ge
Date: Sun Jun 21 2026 - 21:59:07 EST
On 2026/6/20 02:08, Suren Baghdasaryan wrote:
On Fri, Jun 19, 2026 at 4:57 AM Brendan Jackman
<brendan.jackman@xxxxxxxxx> wrote:
On Thu Jun 18, 2026 at 2:22 AM UTC, Hao Ge wrote:
On 2026/6/18 01:14, Brendan Jackman wrote:Oh, I just took a look and it's a bit more fiddly than I thought because
On Wed Jun 17, 2026 at 4:49 PM UTC, Suren Baghdasaryan wrote:
On Wed, Jun 17, 2026 at 9:39 AM Vlastimil Babka (SUSE)Ack. I'll aim to send that tomorrow once Sashiko has caught up.
<vbabka@xxxxxxxxxx> wrote:
+Cc Alexei
On 6/17/26 17:29, Brendan Jackman wrote:
Currently the core allocator code is controlled by ALLOC_NOLOCK, but theIt's not, it's ALLOC_TRYLOCK! Thanks for proving that we need to rename it
to ALLOC_NOLOCK:
https://lore.kernel.org/all/DJ9QPTO2WXNB.10E88ZHWRDHB0@xxxxxxxxx/
So you just won the job to do the rename :) I think it should be done before
this patch, so that the new usages and other _trylock names introduced here
can be done as _nolock outright.
Nice, this actually looks trivial? I can probably just tack it onto theI think this change might also help us in removing __GFP_NO_CODETAGmain entry point function is significantly different from the normalI'll have to ponder it more closely.
__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.
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.
b. Application of current_gfp_context() - also only affects the
slowpath
3. The slowpath itself: this is now just explicitly skipped under
!ALLOC_TRYLOCK.
Ulterior motive: adding an alloc_flags arg to the allocator'sAck.
mm-internal entrypoint can later be used to do more allocation
customisation without needing to create new GFP flags.
v2 for this patch/series.
introduced in [1] and being the only user of __GFP_NO_OBJ_EXT once
Vlastimil's patchset removing other __GFP_NO_OBJ_EXT users lands.
CC'ing Hao as he is brainstorming ways to remove __GFP_NO_CODETAG, and
this might be the answer.
Hi Brendan, Suren,
Thanks for CC'ing me, Suren. This is indeed a viable approach
and I believe it brings us one step closer to removing
__GFP_NO_CODETAG entirely.
Brendan, I'd actually put together a rough local implementation
earlier with mostly the same core idea as yours, and this change
would indeed be minimal based on your patch.
Thanks a lot for being interested in tacking this into your v2 patch series.
alloc_tag.c is actually in lib/ not mm/.
Hi Suren and Bredan
One option is to move alloc_tag.c into mm/ (while keeping more generic
codetag.c in lib/). From a quick look, that seems doable and probably
the easiest approach.
How did you tackle that, can you share your implementation? It would be
nice if we can avoid exposing alloc_flags in gfp.h.
First, I introduced the ALLOC_NO_CODETAG flag as shown below:
@@ -1478,6 +1480,7 @@ unsigned int reclaim_clean_pages_from_list(struct zone *zone,
#define ALLOC_HIGHATOMIC 0x200 /* Allows access to MIGRATE_HIGHATOMIC */
#define ALLOC_TRYLOCK 0x400 /* Only use spin_trylock in allocation path */
#define ALLOC_KSWAPD 0x800 /* allow waking of kswapd, __GFP_KSWAPD_RECLAIM set */
+#define ALLOC_NO_CODETAG 0x1000 /* skip codetag tracking for this allocation */
Then, mirroring __alloc_pages_noprof, we wrapped a helper function named alloc_pages_noprof_notag.
@@ -5252,13 +5335,25 @@ struct page *__alloc_pages_noprof(gfp_t gfp, unsigned int order,
{
struct page *page;
- page = __alloc_frozen_pages_noprof(gfp, order, preferred_nid, nodemask);
+ page = __alloc_frozen_pages_noprof(gfp, order, preferred_nid, nodemask, 0);
if (page)
set_page_refcounted(page);
return page;
}
EXPORT_SYMBOL(__alloc_pages_noprof);
+struct page *alloc_pages_noprof_notag(gfp_t gfp, unsigned int order)
+{
+ struct page *page;
+
+ page = __alloc_frozen_pages_noprof(gfp, order, numa_node_id(), NULL,
+ ALLOC_NO_CODETAG);
+ if (page)
+ set_page_refcounted(page);
+ return page;
+}
+EXPORT_SYMBOL_GPL(alloc_pages_noprof_notag);
Lastly, we exported this function in gfp.h as shown below:
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 51ef13ed756e..ac6e837ac8c0 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -234,6 +234,9 @@ struct folio *__folio_alloc_noprof(gfp_t gfp, unsigned int order, int preferred_
nodemask_t *nodemask);
#define __folio_alloc(...) alloc_hooks(__folio_alloc_noprof(__VA_ARGS__))
+struct page *alloc_pages_noprof_notag(gfp_t gfp, unsigned int order);
+#define alloc_pages_notag(...) alloc_hooks(alloc_pages_noprof_notag(__VA_ARGS__))
Hope this information helps you.
Thanks
Best Regards
Hao