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
*
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;
}
/*
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.
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;
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)
/* 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);
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);