From 0114bb09eb8da9f8cc6259d4fbfeaf43e3252e48 Mon Sep 17 00:00:00 2001 From: Dave Aldridge Date: Fri, 3 Feb 2017 02:24:54 -0800 Subject: [PATCH] sparc64: Stop performance counter before updating This commit takes the fix as implemented in commit b36dd4d8040c and applies it to M8 devices. Original commit message: In order to reliably clear the PCRx.ov bit when updating a performance counter value, we need to stop it counting first. If we do not do this, then we can miss performance counter overflow events. Orabug: 25441707 Signed-off-by: Dave Aldridge Reviewed-by: Shannon Nelson Signed-off-by: Allen Pais --- arch/sparc/kernel/perf_event.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 51950b2420f7..86e532ea5e8b 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -177,11 +177,14 @@ struct sparc_pmu { int upper_shift; int lower_shift; int event_mask; + int ntc_bit; int picnht_bit; + int picnpt_bit; int user_bit; int priv_bit; int hv_bit; int irq_bit; + int ov_bit; int upper_nop; int lower_nop; unsigned int flags; @@ -193,6 +196,8 @@ struct sparc_pmu { int num_pic_regs; }; +static const struct sparc_pmu *sparc_pmu __read_mostly; + static u32 sparc_default_read_pmc(int idx) { u64 val; @@ -758,10 +763,10 @@ static void sparc_vt_write_pmc(int idx, u64 val) pcr = pcr_ops->read_pcr(idx); /* stop the counter */ - pcr_ops->write_pcr(idx, PCR_N4_PICNPT); + pcr_ops->write_pcr(idx, sparc_pmu->picnpt_bit); /* ensure ov and ntc are reset */ - pcr &= ~(PCR_N4_OV | PCR_N4_NTC); + pcr &= ~(sparc_pmu->ov_bit | sparc_pmu->ntc_bit); pcr_ops->write_pic(idx, val & 0xffffffff); @@ -777,6 +782,9 @@ static const struct sparc_pmu niagara4_pmu = { .upper_shift = 5, .lower_shift = 5, .event_mask = 0x7ff, + .ntc_bit = PCR_N4_NTC, + .picnpt_bit = PCR_N4_PICNPT, + .ov_bit = PCR_N4_OV, .user_bit = PCR_N4_UTRACE, .priv_bit = PCR_N4_STRACE, @@ -975,7 +983,10 @@ static const struct sparc_pmu sparc_m7_pmu = { .upper_shift = 5, .lower_shift = 5, .event_mask = 0x7ff, + .ntc_bit = PCR_N4_NTC, .picnht_bit = PCR_N4_PICNHT, + .picnpt_bit = PCR_N4_PICNPT, + .ov_bit = PCR_N4_OV, .user_bit = PCR_N4_UTRACE, .priv_bit = PCR_N4_STRACE, @@ -1162,7 +1173,10 @@ static const struct sparc_pmu sparc_m8_pmu = { .upper_shift = 5, .lower_shift = 5, .event_mask = 0x3fff, + .ntc_bit = PCR_M8_NTC, .picnht_bit = PCR_M8_PICNHT, + .picnpt_bit = PCR_M8_PICNPT, + .ov_bit = PCR_M8_OV, .user_bit = PCR_M8_UTRACE, .priv_bit = PCR_M8_STRACE, @@ -1179,8 +1193,6 @@ static const struct sparc_pmu sparc_m8_pmu = { .num_pic_regs = 4, }; -static const struct sparc_pmu *sparc_pmu __read_mostly; - static u64 event_encoding(u64 event_id, int idx) { if (idx == PIC_UPPER_INDEX) -- 2.50.1