aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events/ring_buffer.c
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2013-10-31 05:19:59 -0400
committerIngo Molnar <mingo@kernel.org>2013-11-06 06:34:18 -0500
commit26c86da8821f7b64fced498674990318bc34c8de (patch)
tree140d2b7c5f0e6e5afd106d3e76793d2be64e8592 /kernel/events/ring_buffer.c
parent83bf9702c876a54e4e4d1735f9c8680a72421fbe (diff)
perf: Simplify the ring-buffer code
By using CIRC_SPACE() we can obviate the need for perf_output_space(). Shrinks the size of perf_output_begin() by 17 bytes on x86_64-defconfig. Signed-off-by: Peter Zijlstra <peterz@infradead.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Cc: Michael Ellerman <michael@ellerman.id.au> Cc: Michael Neuling <mikey@neuling.org> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Cc: james.hogan@imgtec.com Cc: Vince Weaver <vince@deater.net> Cc: Victor Kaplansky <VICTORK@il.ibm.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Anton Blanchard <anton@samba.org> Link: http://lkml.kernel.org/n/tip-vtb0xb0llebmsdlfn1v5vtfj@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/events/ring_buffer.c')
-rw-r--r--kernel/events/ring_buffer.c37
1 files changed, 4 insertions, 33 deletions
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 9c2ddfbf4525..6929c5848d4f 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -12,40 +12,10 @@
12#include <linux/perf_event.h> 12#include <linux/perf_event.h>
13#include <linux/vmalloc.h> 13#include <linux/vmalloc.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/circ_buf.h>
15 16
16#include "internal.h" 17#include "internal.h"
17 18
18static bool perf_output_space(struct ring_buffer *rb, unsigned long tail,
19 unsigned long offset, unsigned long head)
20{
21 unsigned long sz = perf_data_size(rb);
22 unsigned long mask = sz - 1;
23
24 /*
25 * check if user-writable
26 * overwrite : over-write its own tail
27 * !overwrite: buffer possibly drops events.
28 */
29 if (rb->overwrite)
30 return true;
31
32 /*
33 * verify that payload is not bigger than buffer
34 * otherwise masking logic may fail to detect
35 * the "not enough space" condition
36 */
37 if ((head - offset) > sz)
38 return false;
39
40 offset = (offset - tail) & mask;
41 head = (head - tail) & mask;
42
43 if ((int)(head - offset) < 0)
44 return false;
45
46 return true;
47}
48
49static void perf_output_wakeup(struct perf_output_handle *handle) 19static void perf_output_wakeup(struct perf_output_handle *handle)
50{ 20{
51 atomic_set(&handle->rb->poll, POLL_IN); 21 atomic_set(&handle->rb->poll, POLL_IN);
@@ -181,9 +151,10 @@ int perf_output_begin(struct perf_output_handle *handle,
181 tail = ACCESS_ONCE(rb->user_page->data_tail); 151 tail = ACCESS_ONCE(rb->user_page->data_tail);
182 smp_mb(); 152 smp_mb();
183 offset = head = local_read(&rb->head); 153 offset = head = local_read(&rb->head);
184 head += size; 154 if (!rb->overwrite &&
185 if (unlikely(!perf_output_space(rb, tail, offset, head))) 155 unlikely(CIRC_SPACE(head, tail, perf_data_size(rb)) < size))
186 goto fail; 156 goto fail;
157 head += size;
187 } while (local_cmpxchg(&rb->head, offset, head) != offset); 158 } while (local_cmpxchg(&rb->head, offset, head) != offset);
188 159
189 if (head - local_read(&rb->wakeup) > rb->watermark) 160 if (head - local_read(&rb->wakeup) > rb->watermark)