mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
ring-buffer: Show persistent buffer dropped events in trace_pipe file
When the persistent ring buffer is validated on boot up, if a subbuffer is deemed invalid, it resets the buffer and continues. Have the code preserve the RB_MISSED_EVENTS flag in the commit portion of the subbuffer header and pass that back so that the trace_pipe file can show the missed events like the trace file does. For example: <...>-1242 [005] d.... 4429.120116: page_fault_user: address=0x7ffaebb6e728 ip=0x7ffaeb9d4960 error_code=0x7 <...>-1242 [005] ..... 4429.120124: mm_page_alloc: page=00000000055254f3 pfn=0x1373bd order=0 migratetype=1 gfp_flags=GFP_HIGHUSER_MOVABLE|__GFP_COMP <...>-1242 [005] d..2. 4429.120132: tlb_flush: pages:1 reason:local MM shootdown (3) CPU:5 [LOST EVENTS] <...>-1242 [005] d.... 4429.120661: page_fault_user: address=0x55ba7c2d0944 ip=0x55ba7c20cd02 error_code=0x7 <...>-1242 [005] ..... 4429.120669: mm_page_alloc: page=0000000005a02500 pfn=0x12b6e4 order=0 migratetype=1 gfp_flags=GFP_HIGHUSER_MOVABLE|__GFP_COMP <...>-1242 [005] d..2. 4429.120680: tlb_flush: pages:1 reason:local MM shootdown (3) Link: https://patch.msgid.link/20260522171052.156419479@kernel.org Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
parent
97628ff073
commit
8928e4a3be
|
|
@ -5801,6 +5801,7 @@ __rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
|
||||||
struct buffer_page *reader = NULL;
|
struct buffer_page *reader = NULL;
|
||||||
unsigned long overwrite;
|
unsigned long overwrite;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int missed_events = 0;
|
||||||
int nr_loops = 0;
|
int nr_loops = 0;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
|
|
@ -5901,6 +5902,9 @@ __rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
|
||||||
if (!ret)
|
if (!ret)
|
||||||
goto spin;
|
goto spin;
|
||||||
|
|
||||||
|
if (rb_page_commit(reader) & RB_MISSED_EVENTS)
|
||||||
|
missed_events = -1;
|
||||||
|
|
||||||
if (cpu_buffer->ring_meta)
|
if (cpu_buffer->ring_meta)
|
||||||
rb_update_meta_reader(cpu_buffer, reader);
|
rb_update_meta_reader(cpu_buffer, reader);
|
||||||
|
|
||||||
|
|
@ -5965,6 +5969,8 @@ __rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
|
||||||
*/
|
*/
|
||||||
smp_rmb();
|
smp_rmb();
|
||||||
|
|
||||||
|
if (!cpu_buffer->lost_events)
|
||||||
|
cpu_buffer->lost_events = missed_events;
|
||||||
|
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
@ -7066,6 +7072,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
|
||||||
struct buffer_page *reader;
|
struct buffer_page *reader;
|
||||||
long missed_events;
|
long missed_events;
|
||||||
unsigned int commit;
|
unsigned int commit;
|
||||||
|
unsigned int size;
|
||||||
unsigned int read;
|
unsigned int read;
|
||||||
u64 save_timestamp;
|
u64 save_timestamp;
|
||||||
bool force_memcpy;
|
bool force_memcpy;
|
||||||
|
|
@ -7101,7 +7108,8 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
|
||||||
event = rb_reader_event(cpu_buffer);
|
event = rb_reader_event(cpu_buffer);
|
||||||
|
|
||||||
read = reader->read;
|
read = reader->read;
|
||||||
commit = rb_page_size(reader);
|
commit = rb_page_commit(reader);
|
||||||
|
size = rb_page_size(reader);
|
||||||
|
|
||||||
/* Check if any events were dropped */
|
/* Check if any events were dropped */
|
||||||
missed_events = cpu_buffer->lost_events;
|
missed_events = cpu_buffer->lost_events;
|
||||||
|
|
@ -7115,13 +7123,14 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
|
||||||
* we must copy the data from the page to the buffer.
|
* we must copy the data from the page to the buffer.
|
||||||
* Otherwise, we can simply swap the page with the one passed in.
|
* Otherwise, we can simply swap the page with the one passed in.
|
||||||
*/
|
*/
|
||||||
if (read || (len < (commit - read)) ||
|
if (read || (len < (size - read)) ||
|
||||||
cpu_buffer->reader_page == cpu_buffer->commit_page ||
|
cpu_buffer->reader_page == cpu_buffer->commit_page ||
|
||||||
force_memcpy) {
|
force_memcpy) {
|
||||||
struct buffer_data_page *rpage = cpu_buffer->reader_page->page;
|
struct buffer_data_page *rpage = cpu_buffer->reader_page->page;
|
||||||
unsigned int rpos = read;
|
unsigned int rpos = read;
|
||||||
unsigned int pos = 0;
|
unsigned int pos = 0;
|
||||||
unsigned int size;
|
unsigned int event_size;
|
||||||
|
unsigned int flags = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a full page is expected, this can still be returned
|
* If a full page is expected, this can still be returned
|
||||||
|
|
@ -7130,19 +7139,22 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
|
||||||
* the reader page.
|
* the reader page.
|
||||||
*/
|
*/
|
||||||
if (full &&
|
if (full &&
|
||||||
(!read || (len < (commit - read)) ||
|
(!read || (len < (size - read)) ||
|
||||||
cpu_buffer->reader_page == cpu_buffer->commit_page))
|
cpu_buffer->reader_page == cpu_buffer->commit_page))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (len > (commit - read))
|
if (len > (size - read))
|
||||||
len = (commit - read);
|
len = (size - read);
|
||||||
|
|
||||||
/* Always keep the time extend and data together */
|
/* Always keep the time extend and data together */
|
||||||
size = rb_event_ts_length(event);
|
event_size = rb_event_ts_length(event);
|
||||||
|
|
||||||
if (len < size)
|
if (len < event_size)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (commit & RB_MISSED_EVENTS)
|
||||||
|
flags = RB_MISSED_EVENTS;
|
||||||
|
|
||||||
/* save the current timestamp, since the user will need it */
|
/* save the current timestamp, since the user will need it */
|
||||||
save_timestamp = cpu_buffer->read_stamp;
|
save_timestamp = cpu_buffer->read_stamp;
|
||||||
|
|
||||||
|
|
@ -7154,25 +7166,25 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
|
||||||
* one or two events.
|
* one or two events.
|
||||||
* We have already ensured there's enough space if this
|
* We have already ensured there's enough space if this
|
||||||
* is a time extend. */
|
* is a time extend. */
|
||||||
size = rb_event_length(event);
|
event_size = rb_event_length(event);
|
||||||
memcpy(dpage->data + pos, rpage->data + rpos, size);
|
memcpy(dpage->data + pos, rpage->data + rpos, event_size);
|
||||||
|
|
||||||
len -= size;
|
len -= event_size;
|
||||||
|
|
||||||
rb_advance_reader(cpu_buffer);
|
rb_advance_reader(cpu_buffer);
|
||||||
rpos = reader->read;
|
rpos = reader->read;
|
||||||
pos += size;
|
pos += event_size;
|
||||||
|
|
||||||
if (rpos >= commit)
|
if (rpos >= event_size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
event = rb_reader_event(cpu_buffer);
|
event = rb_reader_event(cpu_buffer);
|
||||||
/* Always keep the time extend and data together */
|
/* Always keep the time extend and data together */
|
||||||
size = rb_event_ts_length(event);
|
event_size = rb_event_ts_length(event);
|
||||||
} while (len >= size);
|
} while (len >= event_size);
|
||||||
|
|
||||||
/* update dpage */
|
/* update dpage */
|
||||||
local_set(&dpage->commit, pos);
|
local_set(&dpage->commit, pos | flags);
|
||||||
dpage->time_stamp = save_timestamp;
|
dpage->time_stamp = save_timestamp;
|
||||||
|
|
||||||
/* we copied everything to the beginning */
|
/* we copied everything to the beginning */
|
||||||
|
|
@ -7204,7 +7216,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
|
||||||
|
|
||||||
cpu_buffer->lost_events = 0;
|
cpu_buffer->lost_events = 0;
|
||||||
|
|
||||||
commit = rb_data_page_commit(dpage);
|
size = rb_data_page_size(dpage);
|
||||||
/*
|
/*
|
||||||
* Set a flag in the commit field if we lost events
|
* Set a flag in the commit field if we lost events
|
||||||
*/
|
*/
|
||||||
|
|
@ -7214,11 +7226,11 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
|
||||||
* missed events, then record it there.
|
* missed events, then record it there.
|
||||||
*/
|
*/
|
||||||
if (missed_events > 0 &&
|
if (missed_events > 0 &&
|
||||||
buffer->subbuf_size - commit >= sizeof(missed_events)) {
|
buffer->subbuf_size - size >= sizeof(missed_events)) {
|
||||||
memcpy(&dpage->data[commit], &missed_events,
|
memcpy(&dpage->data[size], &missed_events,
|
||||||
sizeof(missed_events));
|
sizeof(missed_events));
|
||||||
local_add(RB_MISSED_STORED, &dpage->commit);
|
local_add(RB_MISSED_STORED, &dpage->commit);
|
||||||
commit += sizeof(missed_events);
|
size += sizeof(missed_events);
|
||||||
}
|
}
|
||||||
local_add(RB_MISSED_EVENTS, &dpage->commit);
|
local_add(RB_MISSED_EVENTS, &dpage->commit);
|
||||||
}
|
}
|
||||||
|
|
@ -7226,8 +7238,8 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
|
||||||
/*
|
/*
|
||||||
* This page may be off to user land. Zero it out here.
|
* This page may be off to user land. Zero it out here.
|
||||||
*/
|
*/
|
||||||
if (commit < buffer->subbuf_size)
|
if (size < buffer->subbuf_size)
|
||||||
memset(&dpage->data[commit], 0, buffer->subbuf_size - commit);
|
memset(&dpage->data[size], 0, buffer->subbuf_size - size);
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user