From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5A80E3BAD8E for ; Thu, 19 Mar 2026 22:28:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773959290; cv=none; b=m5JDnTjwg5Alq7LQA4cZPlKVrw0K06kFA0yWWqbAmHynd/63C6wo9fasQUUMpf/NYtLTxowf6VxohI45tkEnMh78iwnraWxoV3ElILhyD4E5m2M/9fErYLYVFiwicY7sv4nKg1mQNFlgk5WmTqurV3s9xcT5g85sXIdjpIxsiM8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773959290; c=relaxed/simple; bh=HQBHjY6WL4dQJ8ojlBwwq31sBZ53V4/gE6x2BhV+bhM=; h=Date:From:To:Cc:Subject:Message-Id:In-Reply-To:References: Mime-Version:Content-Type; b=DVjNbwY0RD12TQw7qW9g7/AmlShznHiwY8WSJ/QJw5bTSY/V7o+upzxjta03eg9144evoI/fHBjJUfzZZFNtymB0c5tCu02AnEB883uiupm+D/gg/ovorJUjQzUfZsA3A5OAb4QBDGdupIbLudeOlUz3c/g3iWaJTJQJpDfPsV8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=u2GRaSqc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="u2GRaSqc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 736A1C19424; Thu, 19 Mar 2026 22:28:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1773959289; bh=HQBHjY6WL4dQJ8ojlBwwq31sBZ53V4/gE6x2BhV+bhM=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=u2GRaSqcFmaR6OcoTkut2IibX2qv527mUSd91YmxtV55/w0woORr1WWAB33KRJP9K Pw3euyn9AcAzIWO7wxJy0eTesPAozDjW5+wKhbfQBQ7rEg9XfN2LoO82Y13/6hHW0z tsFCXs7woMStRrTxxy/Krwu+UiEHQpk6M9rt1vBQ= Date: Thu, 19 Mar 2026 15:28:08 -0700 From: Andrew Morton To: Hao Ge Cc: Suren Baghdasaryan , Kent Overstreet , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] mm/alloc_tag: clear codetag for pages allocated before page_ext initialization Message-Id: <20260319152808.fce61386fdf2934d7a3b0edb@linux-foundation.org> In-Reply-To: <20260319083153.2488005-1-hao.ge@linux.dev> References: <20260319083153.2488005-1-hao.ge@linux.dev> X-Mailer: Sylpheed 3.8.0beta1 (GTK+ 2.24.33; x86_64-pc-linux-gnu) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Thu, 19 Mar 2026 16:31:53 +0800 Hao Ge 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, similar to how kmemleak tracks early allocations. > When page_ext initialization completes, set their codetag > to empty to avoid warnings when they are freed later. > > ... > > --- a/include/linux/alloc_tag.h > +++ b/include/linux/alloc_tag.h > @@ -74,6 +74,9 @@ static inline void set_codetag_empty(union codetag_ref *ref) > > #ifdef CONFIG_MEM_ALLOC_PROFILING > > +bool mem_profiling_is_available(void); > +void alloc_tag_add_early_pfn(unsigned long pfn); > + > #define ALLOC_TAG_SECTION_NAME "alloc_tags" > > struct codetag_bytes { > diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c > index 58991ab09d84..a5bf4e72c154 100644 > --- a/lib/alloc_tag.c > +++ b/lib/alloc_tag.c > @@ -6,6 +6,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -26,6 +27,82 @@ static bool mem_profiling_support; > > static struct codetag_type *alloc_tag_cttype; > > +/* > + * State of the alloc_tag > + * > + * This is used to describe the states of the alloc_tag during bootup. > + * > + * When we need to allocate page_ext to store codetag, we face an > + * initialization timing problem: > + * > + * Due to initialization order, pages may be allocated via buddy system > + * before page_ext is fully allocated and initialized. Although these > + * pages call the allocation hooks, the codetag will not be set because > + * page_ext is not yet available. > + * > + * When these pages are later free to the buddy system, it triggers > + * warnings because their codetag is actually empty if > + * CONFIG_MEM_ALLOC_PROFILING_DEBUG is enabled. > + * > + * Additionally, in this situation, we cannot record detailed allocation > + * information for these pages. > + */ > +enum mem_profiling_state { > + DOWN, /* No mem_profiling functionality yet */ > + UP /* Everything is working */ > +}; > + > +static enum mem_profiling_state mem_profiling_state = DOWN; > + > +bool mem_profiling_is_available(void) > +{ > + return mem_profiling_state == UP; > +} > + > +#ifdef CONFIG_MEM_ALLOC_PROFILING_DEBUG > + > +#define EARLY_ALLOC_PFN_MAX 256 > + > +static unsigned long early_pfns[EARLY_ALLOC_PFN_MAX]; It's unfortunate that this isn't __initdata. > +static unsigned int early_pfn_count; > +static DEFINE_SPINLOCK(early_pfn_lock); > + > > ... > > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -1293,6 +1293,13 @@ void __pgalloc_tag_add(struct page *page, struct task_struct *task, > alloc_tag_add(&ref, task->alloc_tag, PAGE_SIZE * nr); > update_page_tag_ref(handle, &ref); > put_page_tag_ref(handle); > + } else { > + /* > + * page_ext is not available yet, record the pfn so we can > + * clear the tag ref later when page_ext is initialized. > + */ > + if (!mem_profiling_is_available()) > + alloc_tag_add_early_pfn(page_to_pfn(page)); > } > } All because of this, I believe. Is this fixable? If we take that `else', we know we're running in __init code, yes? I don't see how `__init pgalloc_tag_add_early()' could be made to work. hrm. Something clever, please.