[PATCH 4/7] tracing: account ring buffer pages and trace_array metadata to memcg
From: Tao Cui
Date: Fri Nov 06 2026 - 08:26:16 EST
From: Tao Cui <cuitao@xxxxxxxxxx>
Creating an instance immediately allocates two full sets of per-cpu
ring buffers, array buffer plus snapshot, about 1.375MB per cpu per set
on the default config, plus the trace_array and its name. None of it
is charged: neither trace.c nor ring_buffer.c passes __GFP_ACCOUNT,
while user_events in the same directory accounts everything it
allocates.
Instance creation is currently gated by tracefs file permissions
alone, so a
rootful container with the host tracefs bound in can create instances
until the host runs out of memory. Charge the ring buffer pages and
the trace_array metadata to the creating cgroup.
Signed-off-by: Tao Cui <cuitao@xxxxxxxxxx>
---
kernel/trace/ring_buffer.c | 8 +++++++-
kernel/trace/trace.c | 6 +++---
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 1fd28a72e6ee..676c059c112c 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -441,7 +441,13 @@ static struct buffer_data_page *alloc_cpu_data(int cpu, int order)
* gracefully without invoking oom-killer and the system is not
* destabilized.
*/
- mflags = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO;
+ /*
+ * The subbuffers are charged to the memcg of whoever caused the
+ * allocation: the creator of a trace instance, or root at boot for
+ * the global trace.
+ */
+ mflags = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO |
+ __GFP_ACCOUNT;
page = alloc_pages_node(cpu_to_node(cpu), mflags, order);
if (!page)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e8c4efa8107b..04b60b9cc4f5 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8693,11 +8693,11 @@ trace_array_create_systems(const char *name, const char *systems,
int ret;
ret = -ENOMEM;
- tr = kzalloc_obj(*tr);
+ tr = kzalloc_obj(*tr, GFP_KERNEL_ACCOUNT);
if (!tr)
return ERR_PTR(ret);
- tr->name = kstrdup(name, GFP_KERNEL);
+ tr->name = kstrdup(name, GFP_KERNEL_ACCOUNT);
if (!tr->name)
goto out_free_tr;
@@ -8708,7 +8708,7 @@ trace_array_create_systems(const char *name, const char *systems,
goto out_free_tr;
if (systems) {
- tr->system_names = kstrdup_const(systems, GFP_KERNEL);
+ tr->system_names = kstrdup_const(systems, GFP_KERNEL_ACCOUNT);
if (!tr->system_names)
goto out_free_tr;
}
--
2.43.0