ring-buffer: Unify ring buffer minimum page calculations

The codebase scatters hardcoded minimum page limits across multiple
places. Introduce RING_BUFFER_MIN_NR_PAGES and rb_calculate_nr_pages()
to formalize the requirement of two pages in a ring buffer.

Link: https://patch.msgid.link/20260911193937.602202-4-vdonnefort@google.com
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
Vincent Donnefort 2026-09-11 20:39:37 +01:00 committed by Steven Rostedt
parent 8acb31975a
commit 20d432b445
3 changed files with 23 additions and 22 deletions

View File

@ -98,6 +98,13 @@ struct trace_buffer *__ring_buffer_alloc_range(unsigned long size, unsigned flag
void *ring_buffer_meta_scratch(struct trace_buffer *buffer, unsigned int *size);
/*
* A minimum of 2 pages ensures we can always swap a page out of the ring
* buffer. This does not account for the reader page or any other page
* containing meta data used by static ring buffers.
*/
#define RING_BUFFER_MIN_NR_PAGES 2UL
/*
* Because the ring buffer is generic, if other users of the ring buffer get
* traced by ftrace, it can produce lockdep warnings. We need to keep each
@ -287,7 +294,7 @@ static inline struct ring_buffer_desc *__first_ring_buffer_desc(struct trace_buf
static inline unsigned long __calc_nr_pages_ring_buffer_desc(size_t size)
{
/* Takes into account the reader page */
return max(DIV_ROUND_UP(size, PAGE_SIZE - BUF_PAGE_HDR_SIZE), 2UL) + 1;
return max(DIV_ROUND_UP(size, PAGE_SIZE - BUF_PAGE_HDR_SIZE), RING_BUFFER_MIN_NR_PAGES) + 1;
}
static inline size_t trace_buffer_desc_size(size_t buffer_size, unsigned int nr_cpus)

View File

@ -642,6 +642,11 @@ static __always_inline unsigned int rb_subbuf_max_data_size(struct trace_buffer
return rb_subbuf_capacity(buffer) - RB_EVNT_HDR_SIZE - sizeof(event->array[0]);
}
static unsigned long rb_calculate_nr_pages(struct trace_buffer *buffer, unsigned long size)
{
return max(DIV_ROUND_UP(size, rb_subbuf_capacity(buffer)), RING_BUFFER_MIN_NR_PAGES);
}
/**
* rb_subbuf_start - Get the start address of a subbuffer
* @buffer: A trace buffer
@ -2864,7 +2869,7 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
goto fail_free_buffers;
/* Need at least two pages plus the reader page */
if (nr_pages < 3)
if (nr_pages < RING_BUFFER_MIN_NR_PAGES + 1)
goto fail_free_buffers;
again:
@ -2876,7 +2881,7 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
ptr += subbuf_size * nr_pages;
}
if (ptr > end) {
if (nr_pages <= 3)
if (nr_pages <= RING_BUFFER_MIN_NR_PAGES + 1)
goto fail_free_buffers;
nr_pages--;
goto again;
@ -2899,13 +2904,10 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
if (nr_pages > rb_static_max_pages())
goto fail_free_buffers;
if (nr_pages < 2)
if (nr_pages < RING_BUFFER_MIN_NR_PAGES)
goto fail_free_buffers;
} else {
/* need at least two pages */
nr_pages = DIV_ROUND_UP(size, rb_subbuf_capacity(buffer));
if (nr_pages < 2)
nr_pages = 2;
nr_pages = rb_calculate_nr_pages(buffer, size);
}
cpumask_set_cpu(cpu, buffer->cpumask);
@ -3318,11 +3320,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
mutex_lock(&buffer->mutex);
atomic_inc(&buffer->resizing);
nr_pages = DIV_ROUND_UP(size, rb_subbuf_capacity(buffer));
/* we need a minimum of two pages */
if (nr_pages < 2)
nr_pages = 2;
nr_pages = rb_calculate_nr_pages(buffer, size);
if (cpu_id == RING_BUFFER_ALL_CPUS) {
/*
@ -7502,12 +7500,8 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order)
}
/* Update the number of pages to match the new size */
nr_pages = old_capacity * buffer->buffers[cpu]->nr_pages;
nr_pages = DIV_ROUND_UP(nr_pages, rb_subbuf_capacity(buffer));
/* we need a minimum of two pages */
if (nr_pages < 2)
nr_pages = 2;
nr_pages = rb_calculate_nr_pages(buffer,
old_capacity * buffer->buffers[cpu]->nr_pages);
cpu_buffer->nr_pages_to_update = nr_pages;
@ -8102,7 +8096,7 @@ int trace_rb_cpu_prepare(unsigned int cpu, struct hlist_node *node)
}
/* allocate minimum pages, user can later expand it */
if (!nr_pages_same)
nr_pages = 2;
nr_pages = RING_BUFFER_MIN_NR_PAGES;
buffer->buffers[cpu] =
rb_allocate_cpu_buffer(buffer, nr_pages, cpu);
if (!buffer->buffers[cpu]) {

View File

@ -383,8 +383,8 @@ int simple_ring_buffer_init_mm(struct simple_rb_per_cpu *cpu_buffer,
void *page;
int i;
/* At least 1 reader page and two pages in the ring-buffer */
if (desc->nr_page_va < 3)
/* At least RING_BUFFER_MIN_NR_PAGES and 1 reader page */
if (desc->nr_page_va < RING_BUFFER_MIN_NR_PAGES + 1)
return -EINVAL;
memset(cpu_buffer, 0, sizeof(*cpu_buffer));