[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250206101936.17791160@gandalf.local.home>
Date: Thu, 6 Feb 2025 10:19:36 -0500
From: Steven Rostedt <rostedt@...dmis.org>
To: "Masami Hiramatsu (Google)" <mhiramat@...nel.org>
Cc: linux-kernel@...r.kernel.org, linux-trace-kernel@...r.kernel.org, Mark
Rutland <mark.rutland@....com>, Mathieu Desnoyers
<mathieu.desnoyers@...icios.com>, Andrew Morton <akpm@...ux-foundation.org>
Subject: Re: [PATCH 2/8] ring-buffer: Add buffer meta data for persistent
ring buffer
On Thu, 6 Feb 2025 14:10:35 +0900
Masami Hiramatsu (Google) <mhiramat@...nel.org> wrote:
> > diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> > index 7146b780176f..0446d053dbd6 100644
> > --- a/kernel/trace/ring_buffer.c
> > +++ b/kernel/trace/ring_buffer.c
> > @@ -49,7 +49,12 @@ static void update_pages_handler(struct work_struct *work);
> >
>
> Can you add a comment to explain the layout of these meta-data and subbufs?
Sure.
>
>
> > struct ring_buffer_meta {
> > int magic;
> > - int struct_size;
> > + int struct_sizes;
> > + unsigned long total_size;
> > + unsigned long buffers_offset;
> > +};
> > +
> > @@ -1664,14 +1674,73 @@ static void *rb_range_buffer(struct ring_buffer_per_cpu *cpu_buffer, int idx)
> > return (void *)ptr;
> > }
> >
> > +/*
> > + * See if the existing memory contains a valid meta section.
> > + * if so, use that, otherwise initialize it.
>
> Note that this must be called only for the persistent ring buffer.
Or just make it return false if bmeta is NULL.
The range_addr_start is only set for persistent ring buffers.
Also, this is to initialize a persistent ring buffer meta data, which makes
calling it for anything else rather strange.
>
> > + */
> > +static bool rb_meta_init(struct trace_buffer *buffer)
> > +{
> > + unsigned long ptr = buffer->range_addr_start;
> > + struct ring_buffer_meta *bmeta;
> > + unsigned long total_size;
> > + int struct_sizes;
> > +
> > + bmeta = (struct ring_buffer_meta *)ptr;
> > + buffer->meta = bmeta;
> > +
> > + total_size = buffer->range_addr_end - buffer->range_addr_start;
> > +
> > + struct_sizes = sizeof(struct ring_buffer_cpu_meta);
> > + struct_sizes |= sizeof(*bmeta) << 16;
> > +
> > + /* The first buffer will start one page after the meta page */
> > + ptr += sizeof(*bmeta);
> > + ptr = ALIGN(ptr, PAGE_SIZE);
> > +
> > + if (bmeta->magic != RING_BUFFER_META_MAGIC) {
> > + pr_info("Ring buffer boot meta mismatch of magic\n");
> > + goto init;
> > + }
> > +
> > + if (bmeta->struct_sizes != struct_sizes) {
> > + pr_info("Ring buffer boot meta mismatch of struct size\n");
> > + goto init;
> > + }
> > +
> > + if (bmeta->total_size != total_size) {
> > + pr_info("Ring buffer boot meta mismatch of total size\n");
> > + goto init;
> > + }
> > +
> > + if (bmeta->buffers_offset > bmeta->total_size) {
> > + pr_info("Ring buffer boot meta mismatch of offset outside of total size\n");
> > + goto init;
> > + }
> > +
> > + if (bmeta->buffers_offset != (void *)ptr - (void *)bmeta) {
> > + pr_info("Ring buffer boot meta mismatch of first buffer offset\n");
> > + goto init;
> > + }
> > +
> > + return true;
> > +
> > @@ -2327,10 +2386,16 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
> >
> > /* If start/end are specified, then that overrides size */
> > if (start && end) {
> > + unsigned long buffers_start;
> > unsigned long ptr;
> > int n;
> >
> > size = end - start;
> > +
> > + /* Subtract the buffer meta data */
> > + size -= PAGE_SIZE;
> > + buffers_start = start + PAGE_SIZE;
> > +
>
> So the buffer meta data is PAGE_SIZE aligned?
It's documented in the reserve_mem to be, but not as a requirement.
I should modify this to not depend on that.
Thanks,
-- Steve
>
> > size = size / nr_cpu_ids;
> >
> > /*
> > @@ -2340,7 +2405,7 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
> > * needed, plus account for the integer array index that
> > * will be appended to the meta data.
> > */
> > - nr_pages = (size - sizeof(struct ring_buffer_meta)) /
> > + nr_pages = (size - sizeof(struct ring_buffer_cpu_meta)) /
> > (subbuf_size + sizeof(int));
> > /* Need at least two pages plus the reader page */
> > if (nr_pages < 3)
> > @@ -2348,8 +2413,8 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
> >
> > again:
> > /* Make sure that the size fits aligned */
> > - for (n = 0, ptr = start; n < nr_cpu_ids; n++) {
> > - ptr += sizeof(struct ring_buffer_meta) +
> > + for (n = 0, ptr = buffers_start; n < nr_cpu_ids; n++) {
> > + ptr += sizeof(struct ring_buffer_cpu_meta) +
> > sizeof(int) * nr_pages;
> > ptr = ALIGN(ptr, subbuf_size);
> > ptr += subbuf_size * nr_pages;
> > @@ -3075,7 +3140,7 @@ static void rb_inc_iter(struct ring_buffer_iter *iter)
> > }
> >
> > /* Return the index into the sub-buffers for a given sub-buffer */
> > -static int rb_meta_subbuf_idx(struct ring_buffer_meta *meta, void *subbuf)
> > +static int rb_meta_subbuf_idx(struct ring_buffer_cpu_meta *meta, void *subbuf)
> > {
> > void *subbuf_array;
> >
> > @@ -3087,7 +3152,7 @@ static int rb_meta_subbuf_idx(struct ring_buffer_meta *meta, void *subbuf)
> > static void rb_update_meta_head(struct ring_buffer_per_cpu *cpu_buffer,
> > struct buffer_page *next_page)
> > {
> > - struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
> > + struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
> > unsigned long old_head = (unsigned long)next_page->page;
> > unsigned long new_head;
> >
> > @@ -3104,7 +3169,7 @@ static void rb_update_meta_head(struct ring_buffer_per_cpu *cpu_buffer,
> > static void rb_update_meta_reader(struct ring_buffer_per_cpu *cpu_buffer,
> > struct buffer_page *reader)
> > {
> > - struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
> > + struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
> > void *old_reader = cpu_buffer->reader_page->page;
> > void *new_reader = reader->page;
> > int id;
> > @@ -3733,7 +3798,7 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
> > rb_page_write(cpu_buffer->commit_page));
> > rb_inc_page(&cpu_buffer->commit_page);
> > if (cpu_buffer->ring_meta) {
> > - struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
> > + struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
> > meta->commit_buffer = (unsigned long)cpu_buffer->commit_page->page;
> > }
> > /* add barrier to keep gcc from optimizing too much */
> > @@ -5986,7 +6051,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
> > if (cpu_buffer->mapped) {
> > rb_update_meta_page(cpu_buffer);
> > if (cpu_buffer->ring_meta) {
> > - struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
> > + struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
> > meta->commit_buffer = meta->head_buffer;
> > }
> > }
> > @@ -6020,7 +6085,7 @@ static void reset_disabled_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
> > void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu)
> > {
> > struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
> > - struct ring_buffer_meta *meta;
> > + struct ring_buffer_cpu_meta *meta;
> >
> > if (!cpumask_test_cpu(cpu, buffer->cpumask))
> > return;
> > @@ -6058,7 +6123,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
> > void ring_buffer_reset_online_cpus(struct trace_buffer *buffer)
> > {
> > struct ring_buffer_per_cpu *cpu_buffer;
> > - struct ring_buffer_meta *meta;
> > + struct ring_buffer_cpu_meta *meta;
> > int cpu;
> >
> > /* prevent another thread from changing buffer sizes */
>
> Thank you,
>
> > --
> > 2.45.2
> >
> >
>
>
Powered by blists - more mailing lists