diff options
| -rw-r--r-- | kernel/trace/ring_buffer.c | 12 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 13 |
2 files changed, 15 insertions, 10 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index c87766c1c204..9ab18995ff1e 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
| @@ -280,6 +280,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data); | |||
| 280 | /* Missed count stored at end */ | 280 | /* Missed count stored at end */ |
| 281 | #define RB_MISSED_STORED (1 << 30) | 281 | #define RB_MISSED_STORED (1 << 30) |
| 282 | 282 | ||
| 283 | #define RB_MISSED_FLAGS (RB_MISSED_EVENTS|RB_MISSED_STORED) | ||
| 284 | |||
| 283 | struct buffer_data_page { | 285 | struct buffer_data_page { |
| 284 | u64 time_stamp; /* page time stamp */ | 286 | u64 time_stamp; /* page time stamp */ |
| 285 | local_t commit; /* write committed index */ | 287 | local_t commit; /* write committed index */ |
| @@ -331,7 +333,9 @@ static void rb_init_page(struct buffer_data_page *bpage) | |||
| 331 | */ | 333 | */ |
| 332 | size_t ring_buffer_page_len(void *page) | 334 | size_t ring_buffer_page_len(void *page) |
| 333 | { | 335 | { |
| 334 | return local_read(&((struct buffer_data_page *)page)->commit) | 336 | struct buffer_data_page *bpage = page; |
| 337 | |||
| 338 | return (local_read(&bpage->commit) & ~RB_MISSED_FLAGS) | ||
| 335 | + BUF_PAGE_HDR_SIZE; | 339 | + BUF_PAGE_HDR_SIZE; |
| 336 | } | 340 | } |
| 337 | 341 | ||
| @@ -4400,8 +4404,13 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data) | |||
| 4400 | { | 4404 | { |
| 4401 | struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; | 4405 | struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; |
| 4402 | struct buffer_data_page *bpage = data; | 4406 | struct buffer_data_page *bpage = data; |
| 4407 | struct page *page = virt_to_page(bpage); | ||
| 4403 | unsigned long flags; | 4408 | unsigned long flags; |
| 4404 | 4409 | ||
| 4410 | /* If the page is still in use someplace else, we can't reuse it */ | ||
| 4411 | if (page_ref_count(page) > 1) | ||
| 4412 | goto out; | ||
| 4413 | |||
| 4405 | local_irq_save(flags); | 4414 | local_irq_save(flags); |
| 4406 | arch_spin_lock(&cpu_buffer->lock); | 4415 | arch_spin_lock(&cpu_buffer->lock); |
| 4407 | 4416 | ||
| @@ -4413,6 +4422,7 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data) | |||
| 4413 | arch_spin_unlock(&cpu_buffer->lock); | 4422 | arch_spin_unlock(&cpu_buffer->lock); |
| 4414 | local_irq_restore(flags); | 4423 | local_irq_restore(flags); |
| 4415 | 4424 | ||
| 4425 | out: | ||
| 4416 | free_page((unsigned long)bpage); | 4426 | free_page((unsigned long)bpage); |
| 4417 | } | 4427 | } |
| 4418 | EXPORT_SYMBOL_GPL(ring_buffer_free_read_page); | 4428 | EXPORT_SYMBOL_GPL(ring_buffer_free_read_page); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 59518b8126d0..2a8d8a294345 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -6769,7 +6769,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
| 6769 | .spd_release = buffer_spd_release, | 6769 | .spd_release = buffer_spd_release, |
| 6770 | }; | 6770 | }; |
| 6771 | struct buffer_ref *ref; | 6771 | struct buffer_ref *ref; |
| 6772 | int entries, size, i; | 6772 | int entries, i; |
| 6773 | ssize_t ret = 0; | 6773 | ssize_t ret = 0; |
| 6774 | 6774 | ||
| 6775 | #ifdef CONFIG_TRACER_MAX_TRACE | 6775 | #ifdef CONFIG_TRACER_MAX_TRACE |
| @@ -6823,14 +6823,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
| 6823 | break; | 6823 | break; |
| 6824 | } | 6824 | } |
| 6825 | 6825 | ||
| 6826 | /* | ||
| 6827 | * zero out any left over data, this is going to | ||
| 6828 | * user land. | ||
| 6829 | */ | ||
| 6830 | size = ring_buffer_page_len(ref->page); | ||
| 6831 | if (size < PAGE_SIZE) | ||
| 6832 | memset(ref->page + size, 0, PAGE_SIZE - size); | ||
| 6833 | |||
| 6834 | page = virt_to_page(ref->page); | 6826 | page = virt_to_page(ref->page); |
| 6835 | 6827 | ||
| 6836 | spd.pages[i] = page; | 6828 | spd.pages[i] = page; |
| @@ -7588,6 +7580,7 @@ allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size | |||
| 7588 | buf->data = alloc_percpu(struct trace_array_cpu); | 7580 | buf->data = alloc_percpu(struct trace_array_cpu); |
| 7589 | if (!buf->data) { | 7581 | if (!buf->data) { |
| 7590 | ring_buffer_free(buf->buffer); | 7582 | ring_buffer_free(buf->buffer); |
| 7583 | buf->buffer = NULL; | ||
| 7591 | return -ENOMEM; | 7584 | return -ENOMEM; |
| 7592 | } | 7585 | } |
| 7593 | 7586 | ||
| @@ -7611,7 +7604,9 @@ static int allocate_trace_buffers(struct trace_array *tr, int size) | |||
| 7611 | allocate_snapshot ? size : 1); | 7604 | allocate_snapshot ? size : 1); |
| 7612 | if (WARN_ON(ret)) { | 7605 | if (WARN_ON(ret)) { |
| 7613 | ring_buffer_free(tr->trace_buffer.buffer); | 7606 | ring_buffer_free(tr->trace_buffer.buffer); |
| 7607 | tr->trace_buffer.buffer = NULL; | ||
| 7614 | free_percpu(tr->trace_buffer.data); | 7608 | free_percpu(tr->trace_buffer.data); |
| 7609 | tr->trace_buffer.data = NULL; | ||
| 7615 | return -ENOMEM; | 7610 | return -ENOMEM; |
| 7616 | } | 7611 | } |
| 7617 | tr->allocated_snapshot = allocate_snapshot; | 7612 | tr->allocated_snapshot = allocate_snapshot; |
