perf/x86/BTS: Fix RCU usage
authorPeter Zijlstra <peterz@infradead.org>
Fri, 18 Mar 2016 16:31:27 +0000 (17:31 +0100)
committerIngo Molnar <mingo@kernel.org>
Mon, 21 Mar 2016 08:08:17 +0000 (09:08 +0100)
This splat reminds us:

[ 8166.045595] [ INFO: suspicious RCU usage. ]

[ 8166.168972]  [<ffffffff81127837>] lockdep_rcu_suspicious+0xe7/0x120
[ 8166.175966]  [<ffffffff811e0bae>] perf_callchain+0x23e/0x250
[ 8166.182280]  [<ffffffff811dda3d>] perf_prepare_sample+0x27d/0x350
[ 8166.189082]  [<ffffffff8100f503>] intel_pmu_drain_bts_buffer+0x133/0x200

... that as the core code does, one should hold rcu_read_lock() over that
entire BTS event-output generation sequence as well.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/events/intel/ds.c

index ce7211a07c0b809767c88481d41127cd6f331b6d..8584b90d8e0bb08e8e9ddc3dd7b6f38dae5363c2 100644 (file)
@@ -570,11 +570,12 @@ int intel_pmu_drain_bts_buffer(void)
         * We will overwrite the from and to address before we output
         * the sample.
         */
+       rcu_read_lock();
        perf_prepare_sample(&header, &data, event, &regs);
 
        if (perf_output_begin(&handle, event, header.size *
                              (top - base - skip)))
-               return 1;
+               goto unlock;
 
        for (at = base; at < top; at++) {
                /* Filter out any records that contain kernel addresses. */
@@ -593,6 +594,8 @@ int intel_pmu_drain_bts_buffer(void)
        /* There's new data available. */
        event->hw.interrupts++;
        event->pending_kill = POLL_IN;
+unlock:
+       rcu_read_unlock();
        return 1;
 }