From: Amit Machhiwal <amachhiw@linux.ibm.com>
To: Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
linux-trace-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
Cc: "Amit Machhiwal" <amachhiw@linux.ibm.com>,
"Michal Suchánek" <msuchanek@suse.de>,
"Vincent Donnefort" <vdonnefort@google.com>,
"Mathieu Desnoyers" <mathieu.desnoyers@efficios.com>,
"Madhavan Srinivasan" <maddy@linux.ibm.com>,
"Ritesh Harjani (IBM)" <ritesh.list@gmail.com>,
"Harsh Prateek Bora" <harshpb@linux.ibm.com>,
linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
kvm-ppc@vger.kernel.org, stable@vger.kernel.org
Subject: [PATCH v2] ring-buffer: Do not check si_mem_available() before deferred init completes
Date: Fri, 16 Oct 2026 19:12:47 +0530 [thread overview]
Message-ID: <20261016134247.70722-1-amachhiw@linux.ibm.com> (raw)
In-Reply-To: <20261009163557.88467-3-amachhiw@linux.ibm.com>
During early boot (early_trace_init() called from start_kernel()),
tracing allocates initial ring buffers (temp_buffer, array_buffer, and
snapshot_buffer) for CPU 0. Later, as secondary CPUs come online during
smp_init(), each CPU's ring buffer is allocated via trace_rb_cpu_prepare().
Before attempting page allocation, __rb_allocate_pages() performs a
heuristic check using si_mem_available() to return early with -ENOMEM if
memory appears insufficient.
However, on kernels built with CONFIG_DEFERRED_STRUCT_PAGE_INIT=y,
NR_FREE_PAGES only reflects the initial non-deferred pool across the entire
period from early_trace_init() through smp_init(). defer_init() leaves
only a single section per node (e.g. 16 MiB with 64 KB pages) initialized
up-front, and on kernels with large static binary footprints (debug
configurations enabling PAGE_OWNER, DEBUG_PAGEALLOC, KFENCE, or SLUB_DEBUG),
early core initialisations (SLUB caches, vmalloc, static ftrace records)
consume virtually all managed pages in this pool.
si_mem_available() therefore returns a false negative (often 0-1 pages)
across both SYSTEM_BOOTING (for the initial CPU 0 buffers) and
SYSTEM_SCHEDULING (for secondary CPU buffers via trace_rb_cpu_prepare()),
causing __rb_allocate_pages() to prematurely abort with -ENOMEM.
This failure is false: the buddy allocator is designed to replenish
ZONE_NORMAL on demand via deferred_grow_zone() when an actual allocation
is attempted. Checking si_mem_available() before calling alloc_pages_node()
short-circuits this on-demand growth entirely.
deferred_grow_zone() is only permanently disabled after page_alloc_init_late()
completes (it spawns per-node kthreads and blocks until done), which happens
inside kernel_init_freeable() — before system_state is set to
SYSTEM_FREEING_INITMEM. Skip the si_mem_available() check until
SYSTEM_FREEING_INITMEM, at which point all deferred pages are initialized
and si_mem_available() is accurate.
Wrap the guard in #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT so that on kernels
without deferred init the original check is preserved unchanged.
Fixes: 2a872fa4e9c8 ("ring-buffer: Check if memory is available before allocation")
Cc: stable@vger.kernel.org
Reported-by: Michal Suchánek <msuchanek@suse.de>
Closes: https://lore.kernel.org/all/arYskzbiaNzBR9MD@kunlun.suse.cz/
Link: https://lore.kernel.org/all/arYskzbiaNzBR9MD@kunlun.suse.cz/
Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
---
Changes since v1:
- Extend the guard to cover SYSTEM_SCHEDULING as well: smp_init() calls
trace_rb_cpu_prepare() -> __rb_allocate_pages() before page_alloc_init_late()
completes, so the false negative window spans both SYSTEM_BOOTING and
SYSTEM_SCHEDULING. Use system_state >= SYSTEM_FREEING_INITMEM as the correct
boundary. (Sashiko, Vincent Donnefort)
- Wrap in #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT to preserve the original
check unchanged on non-deferred kernels. (Vincent Donnefort)
- Drop Tested-by: guard condition changed, requesting fresh test.
kernel/trace/ring_buffer.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 04bb94c29f58..aa877a272c89 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -2452,10 +2452,24 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
* memory. It may not be accurate. But we don't care, we just want
* to prevent doing any allocation when it is obvious that it is
* not going to succeed.
+ *
+ * With CONFIG_DEFERRED_STRUCT_PAGE_INIT, NR_FREE_PAGES only reflects
+ * the initial non-deferred pool during early boot and throughout SMP
+ * bring-up (smp_init() runs before page_alloc_init_late() completes
+ * deferred initialization). si_mem_available() returns a false negative
+ * across this entire window while actual allocations succeed by growing
+ * the zone on demand via deferred_grow_zone(). Only re-enable the check
+ * from SYSTEM_FREEING_INITMEM onward, after page_alloc_init_late() has
+ * finished and si_mem_available() is accurate.
*/
i = si_mem_available();
+#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
+ if (system_state >= SYSTEM_FREEING_INITMEM && i < nr_pages)
+ return -ENOMEM;
+#else
if (i < nr_pages)
return -ENOMEM;
+#endif
/*
* If a user thread allocates too much, and si_mem_available()
base-commit: 2f2f7eeef8b0a1a9b9ca998231419873ccae8d4e
--
2.54.0 (Apple Git-157)
next prev parent reply other threads:[~2026-10-16 13:43 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-09 16:35 [PATCH 0/2] tracing: Fix early boot trace buffer allocation and tracefs init crash Amit Machhiwal
2026-10-09 16:35 ` [PATCH 1/2] tracing: Do not initialize tracefs work if tracing is disabled Amit Machhiwal
2026-10-12 10:04 ` Michal Suchánek
2026-10-13 23:31 ` Masami Hiramatsu
2026-10-09 16:35 ` [PATCH 2/2] ring-buffer: Do not check si_mem_available() during SYSTEM_BOOTING Amit Machhiwal
2026-10-09 16:45 ` sashiko-bot
2026-10-12 10:06 ` Michal Suchánek
2026-10-12 16:38 ` Vincent Donnefort
2026-10-16 13:33 ` Amit Machhiwal
2026-10-16 13:42 ` Amit Machhiwal [this message]
2026-10-16 13:52 ` [PATCH v2] ring-buffer: Do not check si_mem_available() before deferred init completes sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261016134247.70722-1-amachhiw@linux.ibm.com \
--to=amachhiw@linux.ibm.com \
--cc=harshpb@linux.ibm.com \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=msuchanek@suse.de \
--cc=ritesh.list@gmail.com \
--cc=rostedt@goodmis.org \
--cc=stable@vger.kernel.org \
--cc=vdonnefort@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.