perf: Fix wakeup storm for RO mmap()s
authorPeter Zijlstra <a.p.zijlstra@chello.nl>
Thu, 20 May 2010 14:21:55 +0000 (16:21 +0200)
committerIngo Molnar <mingo@elte.hu>
Fri, 21 May 2010 09:37:58 +0000 (11:37 +0200)
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>
include/linux/perf_event.h
kernel/perf_event.c

index 7cd7b356447db128cee59fdff4bfd5b1281c55f8..7098ebbb3b3a1272e4fbb67342f384aac9cbe7c6 100644 (file)
@@ -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  */
index 7a932526946ff573ff175fbff6cb74a4154581ad..1531e0b409a5c5520605b2b300a938925c7dc951 100644 (file)
@@ -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;