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>
This commit is contained in:
parent
83bf9702c8
commit
26c86da882
|
@ -12,40 +12,10 @@
|
||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/circ_buf.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
static bool perf_output_space(struct ring_buffer *rb, unsigned long tail,
|
|
||||||
unsigned long offset, unsigned long head)
|
|
||||||
{
|
|
||||||
unsigned long sz = perf_data_size(rb);
|
|
||||||
unsigned long mask = sz - 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* check if user-writable
|
|
||||||
* overwrite : over-write its own tail
|
|
||||||
* !overwrite: buffer possibly drops events.
|
|
||||||
*/
|
|
||||||
if (rb->overwrite)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* verify that payload is not bigger than buffer
|
|
||||||
* otherwise masking logic may fail to detect
|
|
||||||
* the "not enough space" condition
|
|
||||||
*/
|
|
||||||
if ((head - offset) > sz)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
offset = (offset - tail) & mask;
|
|
||||||
head = (head - tail) & mask;
|
|
||||||
|
|
||||||
if ((int)(head - offset) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void perf_output_wakeup(struct perf_output_handle *handle)
|
static void perf_output_wakeup(struct perf_output_handle *handle)
|
||||||
{
|
{
|
||||||
atomic_set(&handle->rb->poll, POLL_IN);
|
atomic_set(&handle->rb->poll, POLL_IN);
|
||||||
|
@ -181,9 +151,10 @@ int perf_output_begin(struct perf_output_handle *handle,
|
||||||
tail = ACCESS_ONCE(rb->user_page->data_tail);
|
tail = ACCESS_ONCE(rb->user_page->data_tail);
|
||||||
smp_mb();
|
smp_mb();
|
||||||
offset = head = local_read(&rb->head);
|
offset = head = local_read(&rb->head);
|
||||||
head += size;
|
if (!rb->overwrite &&
|
||||||
if (unlikely(!perf_output_space(rb, tail, offset, head)))
|
unlikely(CIRC_SPACE(head, tail, perf_data_size(rb)) < size))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
head += size;
|
||||||
} while (local_cmpxchg(&rb->head, offset, head) != offset);
|
} while (local_cmpxchg(&rb->head, offset, head) != offset);
|
||||||
|
|
||||||
if (head - local_read(&rb->wakeup) > rb->watermark)
|
if (head - local_read(&rb->wakeup) > rb->watermark)
|
||||||
|
|
Loading…
Reference in New Issue