From: Tao Cui <[email protected]> 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 <[email protected]> --- 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
