Skip to content

Commit

Permalink
ring-buffer: Add lost event count to end of sub buffer
Browse files Browse the repository at this point in the history
Currently, binary readers of the ring buffer only know where events were
lost, but not how many events were lost at that location.
This information is available, but it would require adding another
field to the sub buffer header to include it.

But when a event can not fit at the end of a sub buffer, it is written
to the next sub buffer. This means there is a good chance that the
buffer may have room to hold this counter. If it does, write
the counter at the end of the sub buffer and set another flag
in the data size field that states that this information exists.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed Apr 1, 2010
1 parent bc21b47 commit ff0ff84
Showing 1 changed file with 33 additions and 4 deletions.
37 changes: 33 additions & 4 deletions kernel/trace/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data);

/* Flag when events were overwritten */
#define RB_MISSED_EVENTS (1 << 31)
/* Missed count stored at end */
#define RB_MISSED_STORED (1 << 30)

struct buffer_data_page {
u64 time_stamp; /* page time stamp */
Expand All @@ -340,6 +342,7 @@ struct buffer_page {
local_t write; /* index for next write */
unsigned read; /* index for next read */
local_t entries; /* entries on this page */
unsigned long real_end; /* real end of data */
struct buffer_data_page *page; /* Actual data page */
};

Expand Down Expand Up @@ -1769,6 +1772,13 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
event = __rb_page_index(tail_page, tail);
kmemcheck_annotate_bitfield(event, bitfield);

/*
* Save the original length to the meta data.
* This will be used by the reader to add lost event
* counter.
*/
tail_page->real_end = tail;

/*
* If this event is bigger than the minimum size, then
* we need to be careful that we don't subtract the
Expand Down Expand Up @@ -2888,6 +2898,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
local_set(&cpu_buffer->reader_page->write, 0);
local_set(&cpu_buffer->reader_page->entries, 0);
local_set(&cpu_buffer->reader_page->page->commit, 0);
cpu_buffer->reader_page->real_end = 0;

spin:
/*
Expand Down Expand Up @@ -3728,11 +3739,11 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
struct ring_buffer_event *event;
struct buffer_data_page *bpage;
struct buffer_page *reader;
unsigned long missed_events;
unsigned long flags;
unsigned int commit;
unsigned int read;
u64 save_timestamp;
int missed_events = 0;
int ret = -1;

if (!cpumask_test_cpu(cpu, buffer->cpumask))
Expand Down Expand Up @@ -3766,8 +3777,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
commit = rb_page_commit(reader);

/* Check if any events were dropped */
if (cpu_buffer->lost_events)
missed_events = 1;
missed_events = cpu_buffer->lost_events;

/*
* If this page has been partially read or
Expand Down Expand Up @@ -3829,15 +3839,34 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
local_set(&reader->entries, 0);
reader->read = 0;
*data_page = bpage;

/*
* Use the real_end for the data size,
* This gives us a chance to store the lost events
* on the page.
*/
if (reader->real_end)
local_set(&bpage->commit, reader->real_end);
}
ret = read;

cpu_buffer->lost_events = 0;
/*
* Set a flag in the commit field if we lost events
*/
if (missed_events)
if (missed_events) {
commit = local_read(&bpage->commit);

/* If there is room at the end of the page to save the
* missed events, then record it there.
*/
if (BUF_PAGE_SIZE - commit >= sizeof(missed_events)) {
memcpy(&bpage->data[commit], &missed_events,
sizeof(missed_events));
local_add(RB_MISSED_STORED, &bpage->commit);
}
local_add(RB_MISSED_EVENTS, &bpage->commit);
}

out_unlock:
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
Expand Down

0 comments on commit ff0ff84

Please sign in to comment.