[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <1363355028-23278-4-git-send-email-james.hogan@imgtec.com>
Date: Fri, 15 Mar 2013 13:43:42 +0000
From: James Hogan <james.hogan@...tec.com>
To: <linux-kernel@...r.kernel.org>
CC: James Hogan <james.hogan@...tec.com>,
Peter Zijlstra <a.p.zijlstra@...llo.nl>,
Paul Mackerras <paulus@...ba.org>,
Ingo Molnar <mingo@...hat.com>,
Arnaldo Carvalho de Melo <acme@...stprotocols.net>
Subject: [PATCH 3/9] metag: perf: fixes for interrupting perf counters
The overflow handler needs to read modify write when re-enabling the
counter so as not to change the counter value as it may have been
changed to ready the next interrupt on overflow. Similarly for
interrupting counters metag_pmu_enable_counter needs to leave the
counter value unchanged rather than resetting it to zero.
Signed-off-by: James Hogan <james.hogan@...tec.com>
Cc: Peter Zijlstra <a.p.zijlstra@...llo.nl>
Cc: Paul Mackerras <paulus@...ba.org>
Cc: Ingo Molnar <mingo@...hat.com>
Cc: Arnaldo Carvalho de Melo <acme@...stprotocols.net>
---
arch/metag/kernel/perf/perf_event.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/arch/metag/kernel/perf/perf_event.c b/arch/metag/kernel/perf/perf_event.c
index 8096db2..a00f527 100644
--- a/arch/metag/kernel/perf/perf_event.c
+++ b/arch/metag/kernel/perf/perf_event.c
@@ -643,13 +643,15 @@ static void metag_pmu_enable_counter(struct hw_perf_event *event, int idx)
config = tmp >> 4;
}
- /*
- * Enabled counters start from 0. Early cores clear the count on
- * write but newer cores don't, so we make sure that the count is
- * set to 0.
- */
tmp = ((config & 0xf) << 28) |
((1 << 24) << cpu_2_hwthread_id[get_cpu()]);
+ if (metag_pmu->max_period)
+ /*
+ * Cores supporting overflow interrupts may have had the counter
+ * set to a specific value that needs preserving.
+ */
+ tmp |= metag_in32(PERF_COUNT(idx)) & 0x00ffffff;
+
metag_out32(tmp, PERF_COUNT(idx));
unlock:
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
@@ -764,10 +766,16 @@ static irqreturn_t metag_pmu_counter_overflow(int irq, void *dev)
/*
* Enable the counter again once core overflow processing has
- * completed.
+ * completed. Note the counter value may have been modified while it was
+ * inactive to set it up ready for the next interrupt.
*/
- if (!perf_event_overflow(event, &sampledata, regs))
+ if (!perf_event_overflow(event, &sampledata, regs)) {
+ __global_lock2(flags);
+ counter = (counter & 0xff000000) |
+ (metag_in32(PERF_COUNT(idx)) & 0x00ffffff);
metag_out32(counter, PERF_COUNT(idx));
+ __global_unlock2(flags);
+ }
return IRQ_HANDLED;
}
--
1.8.1.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists