Commit 6f807acd authored by Steven Rostedt's avatar Steven Rostedt Committed by Ingo Molnar

ring-buffer: move page indexes into page headers

Remove the global head and tail indexes and move them into the
page header. Each page will now keep track of where the last
write and read was made. We also rename the head and tail to read
and write for better clarification.

This patch is needed for future enhancements to move the ring buffer
to a lockless solution.
Signed-off-by: default avatarSteven Rostedt <srostedt@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 097d036a
...@@ -117,6 +117,8 @@ void *ring_buffer_event_data(struct ring_buffer_event *event) ...@@ -117,6 +117,8 @@ void *ring_buffer_event_data(struct ring_buffer_event *event)
struct buffer_page { struct buffer_page {
u64 time_stamp; /* page time stamp */ u64 time_stamp; /* page time stamp */
unsigned size; /* size of page data */ unsigned size; /* size of page data */
unsigned write; /* index for next write */
unsigned read; /* index for next read */
struct list_head list; /* list of free pages */ struct list_head list; /* list of free pages */
void *page; /* Actual data page */ void *page; /* Actual data page */
}; };
...@@ -153,11 +155,8 @@ struct ring_buffer_per_cpu { ...@@ -153,11 +155,8 @@ struct ring_buffer_per_cpu {
spinlock_t lock; spinlock_t lock;
struct lock_class_key lock_key; struct lock_class_key lock_key;
struct list_head pages; struct list_head pages;
unsigned long head; /* read from head */ struct buffer_page *head_page; /* read from head */
unsigned long tail; /* write to tail */ struct buffer_page *tail_page; /* write to tail */
unsigned long reader;
struct buffer_page *head_page;
struct buffer_page *tail_page;
struct buffer_page *reader_page; struct buffer_page *reader_page;
unsigned long overrun; unsigned long overrun;
unsigned long entries; unsigned long entries;
...@@ -566,10 +565,11 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) ...@@ -566,10 +565,11 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer) static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
{ {
return (cpu_buffer->reader == cpu_buffer->reader_page->size && return cpu_buffer->reader_page->read == cpu_buffer->reader_page->size &&
(cpu_buffer->tail_page == cpu_buffer->reader_page || (cpu_buffer->tail_page == cpu_buffer->reader_page ||
(cpu_buffer->tail_page == cpu_buffer->head_page && (cpu_buffer->tail_page == cpu_buffer->head_page &&
cpu_buffer->head == cpu_buffer->tail))); cpu_buffer->head_page->read ==
cpu_buffer->tail_page->write));
} }
static inline int rb_null_event(struct ring_buffer_event *event) static inline int rb_null_event(struct ring_buffer_event *event)
...@@ -577,7 +577,7 @@ static inline int rb_null_event(struct ring_buffer_event *event) ...@@ -577,7 +577,7 @@ static inline int rb_null_event(struct ring_buffer_event *event)
return event->type == RINGBUF_TYPE_PADDING; return event->type == RINGBUF_TYPE_PADDING;
} }
static inline void *rb_page_index(struct buffer_page *page, unsigned index) static inline void *__rb_page_index(struct buffer_page *page, unsigned index)
{ {
return page->page + index; return page->page + index;
} }
...@@ -585,15 +585,21 @@ static inline void *rb_page_index(struct buffer_page *page, unsigned index) ...@@ -585,15 +585,21 @@ static inline void *rb_page_index(struct buffer_page *page, unsigned index)
static inline struct ring_buffer_event * static inline struct ring_buffer_event *
rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer) rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer)
{ {
return rb_page_index(cpu_buffer->reader_page, return __rb_page_index(cpu_buffer->reader_page,
cpu_buffer->reader); cpu_buffer->reader_page->read);
}
static inline struct ring_buffer_event *
rb_head_event(struct ring_buffer_per_cpu *cpu_buffer)
{
return __rb_page_index(cpu_buffer->head_page,
cpu_buffer->head_page->read);
} }
static inline struct ring_buffer_event * static inline struct ring_buffer_event *
rb_iter_head_event(struct ring_buffer_iter *iter) rb_iter_head_event(struct ring_buffer_iter *iter)
{ {
return rb_page_index(iter->head_page, return __rb_page_index(iter->head_page, iter->head);
iter->head);
} }
/* /*
...@@ -610,7 +616,7 @@ static void rb_update_overflow(struct ring_buffer_per_cpu *cpu_buffer) ...@@ -610,7 +616,7 @@ static void rb_update_overflow(struct ring_buffer_per_cpu *cpu_buffer)
for (head = 0; head < rb_head_size(cpu_buffer); for (head = 0; head < rb_head_size(cpu_buffer);
head += rb_event_length(event)) { head += rb_event_length(event)) {
event = rb_page_index(cpu_buffer->head_page, head); event = __rb_page_index(cpu_buffer->head_page, head);
BUG_ON(rb_null_event(event)); BUG_ON(rb_null_event(event));
/* Only count data entries */ /* Only count data entries */
if (event->type != RINGBUF_TYPE_DATA) if (event->type != RINGBUF_TYPE_DATA)
...@@ -640,13 +646,13 @@ rb_add_stamp(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts) ...@@ -640,13 +646,13 @@ rb_add_stamp(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts)
static void rb_reset_head_page(struct ring_buffer_per_cpu *cpu_buffer) static void rb_reset_head_page(struct ring_buffer_per_cpu *cpu_buffer)
{ {
cpu_buffer->head = 0; cpu_buffer->head_page->read = 0;
} }
static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer) static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
{ {
cpu_buffer->read_stamp = cpu_buffer->reader_page->time_stamp; cpu_buffer->read_stamp = cpu_buffer->reader_page->time_stamp;
cpu_buffer->reader = 0; cpu_buffer->reader_page->read = 0;
} }
static inline void rb_inc_iter(struct ring_buffer_iter *iter) static inline void rb_inc_iter(struct ring_buffer_iter *iter)
...@@ -743,9 +749,8 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, ...@@ -743,9 +749,8 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
struct ring_buffer *buffer = cpu_buffer->buffer; struct ring_buffer *buffer = cpu_buffer->buffer;
struct ring_buffer_event *event; struct ring_buffer_event *event;
/* No locking needed for tail page */
tail_page = cpu_buffer->tail_page; tail_page = cpu_buffer->tail_page;
tail = cpu_buffer->tail; tail = cpu_buffer->tail_page->write;
if (tail + length > BUF_PAGE_SIZE) { if (tail + length > BUF_PAGE_SIZE) {
struct buffer_page *next_page = tail_page; struct buffer_page *next_page = tail_page;
...@@ -774,7 +779,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, ...@@ -774,7 +779,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
} }
if (tail != BUF_PAGE_SIZE) { if (tail != BUF_PAGE_SIZE) {
event = rb_page_index(tail_page, tail); event = __rb_page_index(tail_page, tail);
/* page padding */ /* page padding */
event->type = RINGBUF_TYPE_PADDING; event->type = RINGBUF_TYPE_PADDING;
} }
...@@ -784,14 +789,14 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, ...@@ -784,14 +789,14 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
tail_page->size = 0; tail_page->size = 0;
tail = 0; tail = 0;
cpu_buffer->tail_page = tail_page; cpu_buffer->tail_page = tail_page;
cpu_buffer->tail = tail; cpu_buffer->tail_page->write = tail;
rb_add_stamp(cpu_buffer, ts); rb_add_stamp(cpu_buffer, ts);
spin_unlock(&cpu_buffer->lock); spin_unlock(&cpu_buffer->lock);
} }
BUG_ON(tail + length > BUF_PAGE_SIZE); BUG_ON(tail + length > BUF_PAGE_SIZE);
event = rb_page_index(tail_page, tail); event = __rb_page_index(tail_page, tail);
rb_update_event(event, type, length); rb_update_event(event, type, length);
return event; return event;
...@@ -823,12 +828,12 @@ rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer, ...@@ -823,12 +828,12 @@ rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer,
return -1; return -1;
/* check to see if we went to the next page */ /* check to see if we went to the next page */
if (cpu_buffer->tail) { if (cpu_buffer->tail_page->write) {
/* Still on same page, update timestamp */ /* Still on same page, update timestamp */
event->time_delta = *delta & TS_MASK; event->time_delta = *delta & TS_MASK;
event->array[0] = *delta >> TS_SHIFT; event->array[0] = *delta >> TS_SHIFT;
/* commit the time event */ /* commit the time event */
cpu_buffer->tail += cpu_buffer->tail_page->write +=
rb_event_length(event); rb_event_length(event);
cpu_buffer->write_stamp = *ts; cpu_buffer->write_stamp = *ts;
*delta = 0; *delta = 0;
...@@ -846,7 +851,7 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer, ...@@ -846,7 +851,7 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer,
ts = ring_buffer_time_stamp(cpu_buffer->cpu); ts = ring_buffer_time_stamp(cpu_buffer->cpu);
if (cpu_buffer->tail) { if (cpu_buffer->tail_page->write) {
delta = ts - cpu_buffer->write_stamp; delta = ts - cpu_buffer->write_stamp;
if (test_time_stamp(delta)) { if (test_time_stamp(delta)) {
...@@ -868,7 +873,7 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer, ...@@ -868,7 +873,7 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer,
return NULL; return NULL;
/* If the reserve went to the next page, our delta is zero */ /* If the reserve went to the next page, our delta is zero */
if (!cpu_buffer->tail) if (!cpu_buffer->tail_page->write)
delta = 0; delta = 0;
event->time_delta = delta; event->time_delta = delta;
...@@ -933,8 +938,8 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, ...@@ -933,8 +938,8 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer,
static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer, static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer,
struct ring_buffer_event *event) struct ring_buffer_event *event)
{ {
cpu_buffer->tail += rb_event_length(event); cpu_buffer->tail_page->write += rb_event_length(event);
cpu_buffer->tail_page->size = cpu_buffer->tail; cpu_buffer->tail_page->size = cpu_buffer->tail_page->write;
cpu_buffer->write_stamp += event->time_delta; cpu_buffer->write_stamp += event->time_delta;
cpu_buffer->entries++; cpu_buffer->entries++;
} }
...@@ -1178,10 +1183,10 @@ void ring_buffer_iter_reset(struct ring_buffer_iter *iter) ...@@ -1178,10 +1183,10 @@ void ring_buffer_iter_reset(struct ring_buffer_iter *iter)
/* Iterator usage is expected to have record disabled */ /* Iterator usage is expected to have record disabled */
if (list_empty(&cpu_buffer->reader_page->list)) { if (list_empty(&cpu_buffer->reader_page->list)) {
iter->head_page = cpu_buffer->head_page; iter->head_page = cpu_buffer->head_page;
iter->head = cpu_buffer->head; iter->head = cpu_buffer->head_page->read;
} else { } else {
iter->head_page = cpu_buffer->reader_page; iter->head_page = cpu_buffer->reader_page;
iter->head = cpu_buffer->reader; iter->head = cpu_buffer->reader_page->read;
} }
if (iter->head) if (iter->head)
iter->read_stamp = cpu_buffer->read_stamp; iter->read_stamp = cpu_buffer->read_stamp;
...@@ -1200,7 +1205,7 @@ int ring_buffer_iter_empty(struct ring_buffer_iter *iter) ...@@ -1200,7 +1205,7 @@ int ring_buffer_iter_empty(struct ring_buffer_iter *iter)
cpu_buffer = iter->cpu_buffer; cpu_buffer = iter->cpu_buffer;
return iter->head_page == cpu_buffer->tail_page && return iter->head_page == cpu_buffer->tail_page &&
iter->head == cpu_buffer->tail; iter->head == cpu_buffer->tail_page->write;
} }
static void static void
...@@ -1277,11 +1282,11 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) ...@@ -1277,11 +1282,11 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
reader = cpu_buffer->reader_page; reader = cpu_buffer->reader_page;
/* If there's more to read, return this page */ /* If there's more to read, return this page */
if (cpu_buffer->reader < reader->size) if (cpu_buffer->reader_page->read < reader->size)
goto out; goto out;
/* Never should we have an index greater than the size */ /* Never should we have an index greater than the size */
WARN_ON(cpu_buffer->reader > reader->size); WARN_ON(cpu_buffer->reader_page->read > reader->size);
/* check if we caught up to the tail */ /* check if we caught up to the tail */
reader = NULL; reader = NULL;
...@@ -1342,7 +1347,7 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer) ...@@ -1342,7 +1347,7 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer)
rb_update_read_stamp(cpu_buffer, event); rb_update_read_stamp(cpu_buffer, event);
length = rb_event_length(event); length = rb_event_length(event);
cpu_buffer->reader += length; cpu_buffer->reader_page->read += length;
} }
static void rb_advance_iter(struct ring_buffer_iter *iter) static void rb_advance_iter(struct ring_buffer_iter *iter)
...@@ -1373,7 +1378,7 @@ static void rb_advance_iter(struct ring_buffer_iter *iter) ...@@ -1373,7 +1378,7 @@ static void rb_advance_iter(struct ring_buffer_iter *iter)
* at the tail of the buffer. * at the tail of the buffer.
*/ */
BUG_ON((iter->head_page == cpu_buffer->tail_page) && BUG_ON((iter->head_page == cpu_buffer->tail_page) &&
(iter->head + length > cpu_buffer->tail)); (iter->head + length > cpu_buffer->tail_page->write));
rb_update_iter_read_stamp(iter, event); rb_update_iter_read_stamp(iter, event);
...@@ -1623,7 +1628,9 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) ...@@ -1623,7 +1628,9 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
INIT_LIST_HEAD(&cpu_buffer->reader_page->list); INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
cpu_buffer->reader_page->size = 0; cpu_buffer->reader_page->size = 0;
cpu_buffer->head = cpu_buffer->tail = cpu_buffer->reader = 0; cpu_buffer->head_page->read = 0;
cpu_buffer->tail_page->write = 0;
cpu_buffer->reader_page->read = 0;
cpu_buffer->overrun = 0; cpu_buffer->overrun = 0;
cpu_buffer->entries = 0; cpu_buffer->entries = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment