]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sparc64: Stop performance counter before updating
authorDave Aldridge <david.j.aldridge@oracle.com>
Fri, 3 Feb 2017 10:24:54 +0000 (02:24 -0800)
committerAllen Pais <allen.pais@oracle.com>
Wed, 17 May 2017 07:12:50 +0000 (12:42 +0530)
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 <david.j.aldridge@oracle.com>
Reviewed-by: Shannon Nelson <shannon.nelson@oracle.com>
Signed-off-by: Allen Pais <allen.pais@oracle.com>
arch/sparc/kernel/perf_event.c

index 51950b2420f737d53d5a2f501f6f18d24efd4939..86e532ea5e8bcf7f2b5aaf9e4b32a9018fe70b26 100644 (file)
@@ -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)