Messages in this thread Patch in this message | | | Date | Wed, 29 Sep 2010 19:51:02 +0400 | From | Cyrill Gorcunov <> | Subject | Re: [tip:perf/urgent] perf, x86: Catch spurious interrupts after disabling counters |
| |
On Wed, Sep 29, 2010 at 07:45:28PM +0400, Cyrill Gorcunov wrote: ... > Btw, since x86 architectural and p4 are using same tests for > running I presume better to have some helper rather then > open coded pile? > > Cyrill
Something like this (with some better comment in middle)?
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 6526a86..73a07fb 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1147,6 +1147,16 @@ static void x86_pmu_del(struct perf_event *event, int flags) perf_event_update_userpage(event); } +static inline int x86_pmu_spurious_irq(int idx, struct cpu_hw_events *cpuc) +{ + /* + * Though we deactivated the counter some cpus + * might still deliver spurious interrupts still + * in flight. Catch them: + */ + return __test_and_clear_bit(idx, cpuc->running); +} + static int x86_pmu_handle_irq(struct pt_regs *regs) { struct perf_sample_data data; @@ -1162,13 +1172,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) for (idx = 0; idx < x86_pmu.num_counters; idx++) { 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++; + handled += x86_pmu_spurious_irq(idx, cpuc); continue; } diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index c70c878..524325c 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -904,8 +904,10 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) for (idx = 0; idx < x86_pmu.num_counters; idx++) { int overflow; - if (!test_bit(idx, cpuc->active_mask)) + if (!test_bit(idx, cpuc->active_mask)) { + handled += x86_pmu_spurious_irq(idx, cpuc); continue; + } event = cpuc->events[idx]; hwc = &event->hw;
| |