Commit-ID: 63e6be6d98e1a2bcdca86872b67052e51ab6afa1 Gitweb: http://git.kernel.org/tip/63e6be6d98e1a2bcdca86872b67052e51ab6afa1 Author: Robert Richter <robert.richter@xxxxxxx> AuthorDate: Wed, 15 Sep 2010 18:20:34 +0200 Committer: Ingo Molnar <mingo@xxxxxxx> CommitDate: Fri, 24 Sep 2010 12:21:41 +0200 perf, x86: Catch spurious interrupts after disabling counters Some cpus still deliver spurious interrupts after disabling a counter. This caused 'undelivered NMI' messages. This patch fixes this. Introduced by: 4177c42: perf, x86: Try to handle unknown nmis with an enabled PMU Reported-by: Ingo Molnar <mingo@xxxxxxx> Signed-off-by: Robert Richter <robert.richter@xxxxxxx> Cc: Don Zickus <dzickus@xxxxxxxxxx> Cc: gorcunov@xxxxxxxxx <gorcunov@xxxxxxxxx> Cc: fweisbec@xxxxxxxxx <fweisbec@xxxxxxxxx> Cc: ying.huang@xxxxxxxxx <ying.huang@xxxxxxxxx> Cc: ming.m.lin@xxxxxxxxx <ming.m.lin@xxxxxxxxx> Cc: yinghai@xxxxxxxxxx <yinghai@xxxxxxxxxx> Cc: andi@xxxxxxxxxxxxxx <andi@xxxxxxxxxxxxxx> Cc: eranian@xxxxxxxxxx <eranian@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> LKML-Reference: <20100915162034.GO13563@xxxxxxxxxxxx> Signed-off-by: Ingo Molnar <mingo@xxxxxxx> --- arch/x86/kernel/cpu/perf_event.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 3efdf28..03a5b03 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -102,6 +102,7 @@ struct cpu_hw_events { */ struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; int enabled; int n_events; @@ -1010,6 +1011,7 @@ static int x86_pmu_start(struct perf_event *event) x86_perf_event_set_period(event); cpuc->events[idx] = event; __set_bit(idx, cpuc->active_mask); + __set_bit(idx, cpuc->running); x86_pmu.enable(event); perf_event_update_userpage(event); @@ -1141,8 +1143,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) cpuc = &__get_cpu_var(cpu_hw_events); for (idx = 0; idx < x86_pmu.num_counters; idx++) { - if (!test_bit(idx, cpuc->active_mask)) + if (!test_bit(idx, cpuc->active_mask)) { + /* + * Though we deactivated the counter some cpus + * might still deliver spurious interrupts still + * in flight. Catch them: + */ + if (__test_and_clear_bit(idx, cpuc->running)) + handled++; continue; + } event = cpuc->events[idx]; hwc = &event->hw; -- To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html
![]() |