The ring buffer order can be dynamically modified and temporarily
disables writing to do so. It is therefore safe to use the updated value
to calculate the maximum event size which can be written onto the ring
buffer.
However, notice it is hardly making any difference for trace_marker
because of the TRACE_MARKER_MAX_SIZE limit. For an 8KiB subbuf size,
trace_marker can take 4096 characters while it can 'only' take 4054
bytes for smaller subbufs.
Fixes: f9b94daa542a ("ring-buffer: Set new size of the ring buffer sub page")
Signed-off-by: Vincent Donnefort <[email protected]>
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 29901668e18c..026658c70351 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -592,7 +592,6 @@ struct trace_buffer {
struct ring_buffer_meta *meta;
unsigned int subbuf_order;
- unsigned int max_data_size;
};
static __always_inline unsigned int rb_subbuf_size(struct trace_buffer *buffer)
@@ -605,6 +604,17 @@ static __always_inline unsigned int
rb_subbuf_capacity(struct trace_buffer *buff
return rb_subbuf_size(buffer) - BUF_PAGE_HDR_SIZE;
}
+static __always_inline unsigned int rb_max_data_size(struct trace_buffer
*buffer)
+{
+ struct ring_buffer_event *event;
+
+ /*
+ * surely rb_subbuf_capacity() is bigger than
+ * RINGBUF_TYPE_DATA_TYPE_LEN_MAX (see ring_buffer_event_length).
+ */
+ return rb_subbuf_capacity(buffer) - RB_EVNT_HDR_SIZE -
sizeof(event->array[0]);
+}
+
struct ring_buffer_iter {
struct ring_buffer_per_cpu *cpu_buffer;
unsigned long head;
@@ -2745,9 +2755,6 @@ static struct trace_buffer *alloc_buffer(unsigned long
size, unsigned flags,
buffer->subbuf_order = order;
subbuf_size = (PAGE_SIZE << order);
- /* Max payload is buffer page size - header (8bytes) */
- buffer->max_data_size = rb_subbuf_capacity(buffer) - (sizeof(u32) * 2);
-
buffer->flags = flags;
buffer->clock = trace_clock_local;
buffer->reader_lock_key = key;
@@ -4914,7 +4921,7 @@ rb_reserve_next_event(struct trace_buffer *buffer,
if (ring_buffer_time_stamp_abs(cpu_buffer->buffer)) {
add_ts_default = RB_ADD_STAMP_ABSOLUTE;
info.length += RB_LEN_TIME_EXTEND;
- if (info.length > cpu_buffer->buffer->max_data_size)
+ if (info.length > rb_max_data_size(cpu_buffer->buffer))
goto out_fail;
} else {
add_ts_default = RB_ADD_STAMP_NONE;
@@ -4989,7 +4996,7 @@ ring_buffer_lock_reserve(struct trace_buffer *buffer,
unsigned long length)
if (unlikely(atomic_read(&cpu_buffer->record_disabled)))
goto out;
- if (unlikely(length > buffer->max_data_size))
+ if (unlikely(length > rb_max_data_size(buffer)))
goto out;
if (unlikely(trace_recursive_lock(cpu_buffer)))
@@ -5136,7 +5143,7 @@ int ring_buffer_write(struct trace_buffer *buffer,
if (atomic_read(&cpu_buffer->record_disabled))
return -EBUSY;
- if (length > buffer->max_data_size)
+ if (length > rb_max_data_size(buffer))
return -EBUSY;
if (unlikely(trace_recursive_lock(cpu_buffer)))
@@ -6495,8 +6502,9 @@ unsigned long ring_buffer_max_event_size(struct
trace_buffer *buffer)
{
/* If abs timestamp is requested, events have a timestamp too */
if (ring_buffer_time_stamp_abs(buffer))
- return buffer->max_data_size - RB_LEN_TIME_EXTEND;
- return buffer->max_data_size;
+ return rb_max_data_size(buffer) - RB_LEN_TIME_EXTEND;
+
+ return rb_max_data_size(buffer);
}
EXPORT_SYMBOL_GPL(ring_buffer_max_event_size);
--
2.55.0.654.g21b8a5bc05-goog