On Thu, 6 Feb 2025 14:10:35 +0900
Masami Hiramatsu (Google) <mhira...@kernel.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
> > 
> >   
> 
> 


Reply via email to