Skip to content

Commit

Permalink
ring-buffer: make ring_buffer_read_page read from start on partial page
Browse files Browse the repository at this point in the history
Impact: dont leave holes in read buffer page

The ring_buffer_read_page swaps a given page with the reader page
of the ring buffer, if certain conditions are set:

 1) requested length is big enough to hold entire page data

 2) a writer is not currently on the page

 3) the page is not partially consumed.

Instead of swapping with the supplied page. It copies the data to
the supplied page instead. But currently the data is copied in the
same offset as the source page. This causes a hole at the start
of the reader page. This complicates the use of this function.
Instead, it should copy the data at the beginning of the function
and update the index fields accordingly.

Other small clean ups are also done in this patch.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
  • Loading branch information
Steven Rostedt committed Mar 4, 2009
1 parent e3d6bf0 commit 474d32b
Showing 1 changed file with 33 additions and 10 deletions.
43 changes: 33 additions & 10 deletions kernel/trace/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ enum {

static unsigned long ring_buffer_flags __read_mostly = RB_BUFFERS_ON;

#define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data)

/**
* tracing_on - enable all tracing buffers
*
Expand Down Expand Up @@ -234,9 +236,16 @@ static void rb_init_page(struct buffer_data_page *bpage)
local_set(&bpage->commit, 0);
}

/**
* ring_buffer_page_len - the size of data on the page.
* @page: The page to read
*
* Returns the amount of data on the page, including buffer page header.
*/
size_t ring_buffer_page_len(void *page)
{
return local_read(&((struct buffer_data_page *)page)->commit);
return local_read(&((struct buffer_data_page *)page)->commit)
+ BUF_PAGE_HDR_SIZE;
}

/*
Expand All @@ -259,7 +268,7 @@ static inline int test_time_stamp(u64 delta)
return 0;
}

#define BUF_PAGE_SIZE (PAGE_SIZE - offsetof(struct buffer_data_page, data))
#define BUF_PAGE_SIZE (PAGE_SIZE - BUF_PAGE_HDR_SIZE)

/*
* head_page == tail_page && head == tail then buffer is empty.
Expand Down Expand Up @@ -2454,6 +2463,15 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
unsigned int read;
int ret = -1;

/*
* If len is not big enough to hold the page header, then
* we can not copy anything.
*/
if (len <= BUF_PAGE_HDR_SIZE)
return -1;

len -= BUF_PAGE_HDR_SIZE;

if (!data_page)
return -1;

Expand All @@ -2473,15 +2491,17 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
commit = rb_page_commit(reader);

/*
* If len > what's left on the page, and the writer is also off of
* the read page, then simply switch the read page with the given
* page. Otherwise we need to copy the data from the reader to the
* writer.
* If this page has been partially read or
* if len is not big enough to read the rest of the page or
* a writer is still on the page, then
* we must copy the data from the page to the buffer.
* Otherwise, we can simply swap the page with the one passed in.
*/
if ((len < (commit - read)) ||
if (read || (len < (commit - read)) ||
cpu_buffer->reader_page == cpu_buffer->commit_page) {
struct buffer_data_page *rpage = cpu_buffer->reader_page->page;
unsigned int pos = read;
unsigned int rpos = read;
unsigned int pos = 0;
unsigned int size;

if (full)
Expand All @@ -2497,12 +2517,13 @@ int ring_buffer_read_page(struct ring_buffer *buffer,

/* Need to copy one event at a time */
do {
memcpy(bpage->data + pos, rpage->data + pos, size);
memcpy(bpage->data + pos, rpage->data + rpos, size);

len -= size;

rb_advance_reader(cpu_buffer);
pos = reader->read;
rpos = reader->read;
pos += size;

event = rb_reader_event(cpu_buffer);
size = rb_event_length(event);
Expand All @@ -2512,6 +2533,8 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
local_set(&bpage->commit, pos);
bpage->time_stamp = rpage->time_stamp;

/* we copied everything to the beginning */
read = 0;
} else {
/* swap the pages */
rb_init_page(bpage);
Expand Down

0 comments on commit 474d32b

Please sign in to comment.