Re: [PATCH v4] mm/alloc_tag: clear codetag for pages allocated before page_ext initialization
From: Andrew Morton
Date: Tue Mar 31 2026 - 22:39:44 EST
On Tue, 31 Mar 2026 16:13:12 +0800 Hao Ge <hao.ge@xxxxxxxxx> wrote:
> Due to initialization ordering, page_ext is allocated and initialized
> relatively late during boot. Some pages have already been allocated
> and freed before page_ext becomes available, leaving their codetag
> uninitialized.
>
> A clear example is in init_section_page_ext(): alloc_page_ext() calls
> kmemleak_alloc(). If the slab cache has no free objects, it falls back
> to the buddy allocator to allocate memory. However, at this point page_ext
> is not yet fully initialized, so these newly allocated pages have no
> codetag set. These pages may later be reclaimed by KASAN, which causes
> the warning to trigger when they are freed because their codetag ref is
> still empty.
>
> Use a global array to track pages allocated before page_ext is fully
> initialized. The array size is fixed at 8192 entries, and will emit
> a warning if this limit is exceeded. When page_ext initialization
> completes, set their codetag to empty to avoid warnings when they
> are freed later.
>
> This warning is only observed with CONFIG_MEM_ALLOC_PROFILING_DEBUG=Y
> and mem_profiling_compressed disabled:
>
> [ 9.582133] ------------[ cut here ]------------
> [ 9.582137] alloc_tag was not set
>
> ...
>
Thanks.
> v4: Fix sparse warnings by changing the typedef from a function pointer
> type to a function type, and placing __rcu before the pointer
> declarator. Use RCU_INITIALIZER() for static initialization.
> Closes: https://lore.kernel.org/oe-kbuild-all/202603291211.YhY0R0se-lkp@xxxxxxxxx/
fwiw, here's the delta relative to v3:
--- a/lib/alloc_tag.c~mm-alloc_tag-clear-codetag-for-pages-allocated-before-page_ext-initialization-v4
+++ a/lib/alloc_tag.c
@@ -800,13 +800,13 @@ static void __init __alloc_tag_add_early
early_pfns[old_idx] = pfn;
}
-typedef void (*alloc_tag_add_func)(unsigned long pfn);
-static alloc_tag_add_func __rcu alloc_tag_add_early_pfn_ptr __refdata =
- __alloc_tag_add_early_pfn;
+typedef void alloc_tag_add_func(unsigned long pfn);
+static alloc_tag_add_func __rcu *alloc_tag_add_early_pfn_ptr __refdata =
+ RCU_INITIALIZER(__alloc_tag_add_early_pfn);
void alloc_tag_add_early_pfn(unsigned long pfn)
{
- alloc_tag_add_func alloc_tag_add;
+ alloc_tag_add_func *alloc_tag_add;
if (static_key_enabled(&mem_profiling_compressed))
return;
_