summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2010-05-20 16:21:55 +0200
committerIngo Molnar <mingo@elte.hu>2010-05-21 11:37:58 +0200
commitadb8e118f288dc4c569ac9a89010b81a4745fbf0 (patch)
tree40f2bbbe7c59fb4b4a44120fa9cc79822b68e545
parent0e2e63dd608bf5844ffae7bf7d860de18a62724c (diff)
perf: Fix wakeup storm for RO mmap()s
RO mmap()s don't update the tail pointer, so comparing against it for determining the written data size doesn't really do any good. Keep track of when we last did a wakeup, and compare against that. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Steven Rostedt <rostedt@goodmis.org> LKML-Reference: <20100521090710.684479310@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/perf_event.h2
-rw-r--r--kernel/perf_event.c4
2 files changed, 3 insertions, 3 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 7cd7b356447..7098ebbb3b3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -599,7 +599,7 @@ struct perf_mmap_data {
local_t head; /* write position */
local_t nest; /* nested writers */
local_t events; /* event limit */
- local_t wakeup; /* needs a wakeup */
+ local_t wakeup; /* wakeup stamp */
local_t lost; /* nr records lost */
long watermark; /* wakeup watermark */
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 7a932526946..1531e0b409a 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -3056,8 +3056,8 @@ int perf_output_begin(struct perf_output_handle *handle,
handle->offset = offset;
handle->head = head;
- if (head - tail > data->watermark)
- local_inc(&data->wakeup);
+ if (head - local_read(&data->wakeup) > data->watermark)
+ local_add(data->watermark, &data->wakeup);
if (have_lost) {
lost_event.header.type = PERF_RECORD_LOST;