On Fri, Sep 11, 2026 at 11:50:16PM +0800, Xiang Gao wrote:
> +     /* The cached read page, if present, is a full sub-buffer page. */
> +     if (cpu_buffer->free_page)
> +             size += subbuf_size;

Have you compile-tested this one? free_page is a struct, not a pointer:

  kernel/trace/ring_buffer.c:6594:13: error: used struct type value where 
scalar is required
   6594 |         if (cpu_buffer->free_page)
        |             ^~~~~~~~~~

cpu_buffer->free_page.data should do it.

> +     list_for_each_entry(tr, &ftrace_trace_arrays, list) {
> +             for_each_tracing_cpu(cpu)
> +                     trace_array_buffer_memory(tr, cpu, &stats.buffers,
> +                                               &stats.snapshot);
> +     }

With that fixed the walk does match the changelog, but temp_buffer is out
of its reach. tracer_alloc_buffers() allocates it and never attaches it to
a trace array, so it is not on ftrace_trace_arrays, and its pages are the
kind you are counting: sub-buffers and a reader page from the page
allocator, not remote and not slab.

It is three sub-buffers per CPU at order 0 and is never resized, so it
disappears into the noise once a real buffer is sized up. At rest it does
not. On an 8 CPU x86_64 guest the file reports

  buffers: 96

while temp_buffer holds another 96K. Freeing it hands back 24 pages, which
is what ring_buffer_memory_size() predicts for it.

Was that deliberate? For lost RAM accounting I would have expected it in.

Reply via email to