|
@@ -280,6 +280,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data);
|
|
|
/* Missed count stored at end */
|
|
|
#define RB_MISSED_STORED (1 << 30)
|
|
|
|
|
|
+#define RB_MISSED_FLAGS (RB_MISSED_EVENTS|RB_MISSED_STORED)
|
|
|
+
|
|
|
struct buffer_data_page {
|
|
|
u64 time_stamp; /* page time stamp */
|
|
|
local_t commit; /* write committed index */
|
|
@@ -331,7 +333,9 @@ static void rb_init_page(struct buffer_data_page *bpage)
|
|
|
*/
|
|
|
size_t ring_buffer_page_len(void *page)
|
|
|
{
|
|
|
- return local_read(&((struct buffer_data_page *)page)->commit)
|
|
|
+ struct buffer_data_page *bpage = page;
|
|
|
+
|
|
|
+ return (local_read(&bpage->commit) & ~RB_MISSED_FLAGS)
|
|
|
+ BUF_PAGE_HDR_SIZE;
|
|
|
}
|
|
|
|
|
@@ -4400,8 +4404,13 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data)
|
|
|
{
|
|
|
struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
|
|
|
struct buffer_data_page *bpage = data;
|
|
|
+ struct page *page = virt_to_page(bpage);
|
|
|
unsigned long flags;
|
|
|
|
|
|
+ /* If the page is still in use someplace else, we can't reuse it */
|
|
|
+ if (page_ref_count(page) > 1)
|
|
|
+ goto out;
|
|
|
+
|
|
|
local_irq_save(flags);
|
|
|
arch_spin_lock(&cpu_buffer->lock);
|
|
|
|
|
@@ -4413,6 +4422,7 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data)
|
|
|
arch_spin_unlock(&cpu_buffer->lock);
|
|
|
local_irq_restore(flags);
|
|
|
|
|
|
+ out:
|
|
|
free_page((unsigned long)bpage);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ring_buffer_free_read_page);
|