Messages in this thread Patch in this message | | | From | Alexander Shishkin <> | Subject | [PATCH v4 16/22] perf: Add rb_{alloc,free}_kernel api | Date | Wed, 20 Aug 2014 15:36:13 +0300 |
| |
Events that generate AUX data can also be created by the kernel. In this case, some in-kernel infrastructure is needed to store and copy this data.
This patch adds api for ring buffer (de-)allocation that can be used by the kernel code.
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> --- kernel/events/internal.h | 3 +++ kernel/events/ring_buffer.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+)
diff --git a/kernel/events/internal.h b/kernel/events/internal.h index 4f99987bc3..f4cfa4cabb 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h @@ -59,6 +59,9 @@ extern void perf_event_wakeup(struct perf_event *event); extern int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event, pgoff_t pgoff, int nr_pages, long watermark, int flags); extern void rb_free_aux(struct ring_buffer *rb, struct perf_event *event); +extern struct ring_buffer * +rb_alloc_kernel(struct perf_event *event, int nr_pages, int aux_nr_pages); +extern void rb_free_kernel(struct ring_buffer *rb, struct perf_event *event); extern struct ring_buffer *ring_buffer_get(struct perf_event *event); extern void ring_buffer_put(struct ring_buffer *rb); diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 27d1dd7cfa..7887601aa5 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -464,6 +464,39 @@ void rb_free_aux(struct ring_buffer *rb, struct perf_event *event) rb->aux_nr_pages = 0; } +struct ring_buffer * +rb_alloc_kernel(struct perf_event *event, int nr_pages, int aux_nr_pages) +{ + struct ring_buffer *rb; + int ret, pgoff = nr_pages + 1; + + rb = rb_alloc(nr_pages, 0, event->cpu, 0); + if (!rb) + return NULL; + + ret = rb_alloc_aux(rb, event, pgoff, aux_nr_pages, 0, 0); + if (ret) { + rb_free(rb); + return NULL; + } + + /* + * Kernel counters don't need ring buffer wakeups, therefore we don't + * use ring_buffer_attach() here and event->rb_entry stays empty + */ + rcu_assign_pointer(event->rb, rb); + + return rb; +} + +void rb_free_kernel(struct ring_buffer *rb, struct perf_event *event) +{ + BUG_ON(atomic_read(&rb->refcount) != 1); + rcu_assign_pointer(event->rb, NULL); + rb_free_aux(rb, event); + rb_free(rb); +} + #ifndef CONFIG_PERF_USE_VMALLOC /* -- 2.1.0
| |