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:
Родитель
83bf9702c8
Коммит
26c86da882
|
@ -12,40 +12,10 @@
|
|||
#include <linux/perf_event.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/circ_buf.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)
|
||||
{
|
||||
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);
|
||||
smp_mb();
|
||||
offset = head = local_read(&rb->head);
|
||||
head += size;
|
||||
if (unlikely(!perf_output_space(rb, tail, offset, head)))
|
||||
if (!rb->overwrite &&
|
||||
unlikely(CIRC_SPACE(head, tail, perf_data_size(rb)) < size))
|
||||
goto fail;
|
||||
head += size;
|
||||
} while (local_cmpxchg(&rb->head, offset, head) != offset);
|
||||
|
||||
if (head - local_read(&rb->wakeup) > rb->watermark)
|
||||
|
|
Загрузка…
Ссылка в новой задаче