* [PATCH 2/6] powerpc/perf: factor out power8 pmu functions
2016-06-26 17:37 [PATCH 1/6] powerpc/perf: factor out power8 pmu macros and defines Madhavan Srinivasan
@ 2016-06-26 17:37 ` Madhavan Srinivasan
2016-06-26 17:37 ` [PATCH 3/6] powerpc/perf: factor out power8 __init_pmu code Madhavan Srinivasan
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Madhavan Srinivasan @ 2016-06-26 17:37 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, Madhavan Srinivasan
Factor out some of the power8 pmu functions
to new file "isa207-common.c" to share with
power9 pmu code. Only code movement and no
logic change
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/perf/Makefile | 2 +-
arch/powerpc/perf/isa207-common.c | 263 ++++++++++++++++++++++++++++++++++++++
arch/powerpc/perf/isa207-common.h | 6 +
arch/powerpc/perf/power8-pmu.c | 256 +------------------------------------
4 files changed, 273 insertions(+), 254 deletions(-)
create mode 100644 arch/powerpc/perf/isa207-common.c
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 77b6394a7c50..92f8ea46238b 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o
obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \
power5+-pmu.o power6-pmu.o power7-pmu.o \
- power8-pmu.o
+ isa207-common.o power8-pmu.o
obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c
new file mode 100644
index 000000000000..6143c99f3ec5
--- /dev/null
+++ b/arch/powerpc/perf/isa207-common.c
@@ -0,0 +1,263 @@
+/*
+ * Common Performance counter support functions for PowerISA v2.07 processors.
+ *
+ * Copyright 2009 Paul Mackerras, IBM Corporation.
+ * Copyright 2013 Michael Ellerman, IBM Corporation.
+ * Copyright 2016 Madhavan Srinivasan, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "isa207-common.h"
+
+static inline bool event_is_fab_match(u64 event)
+{
+ /* Only check pmc, unit and pmcxsel, ignore the edge bit (0) */
+ event &= 0xff0fe;
+
+ /* PM_MRK_FAB_RSP_MATCH & PM_MRK_FAB_RSP_MATCH_CYC */
+ return (event == 0x30056 || event == 0x4f052);
+}
+
+int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp)
+{
+ unsigned int unit, pmc, cache, ebb;
+ unsigned long mask, value;
+
+ mask = value = 0;
+
+ if (event & ~EVENT_VALID_MASK)
+ return -1;
+
+ pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
+ unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK;
+ cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK;
+ ebb = (event >> EVENT_EBB_SHIFT) & EVENT_EBB_MASK;
+
+ if (pmc) {
+ u64 base_event;
+
+ if (pmc > 6)
+ return -1;
+
+ /* Ignore Linux defined bits when checking event below */
+ base_event = event & ~EVENT_LINUX_MASK;
+
+ if (pmc >= 5 && base_event != 0x500fa &&
+ base_event != 0x600f4)
+ return -1;
+
+ mask |= CNST_PMC_MASK(pmc);
+ value |= CNST_PMC_VAL(pmc);
+ }
+
+ if (pmc <= 4) {
+ /*
+ * Add to number of counters in use. Note this includes events with
+ * a PMC of 0 - they still need a PMC, it's just assigned later.
+ * Don't count events on PMC 5 & 6, there is only one valid event
+ * on each of those counters, and they are handled above.
+ */
+ mask |= CNST_NC_MASK;
+ value |= CNST_NC_VAL;
+ }
+
+ if (unit >= 6 && unit <= 9) {
+ /*
+ * L2/L3 events contain a cache selector field, which is
+ * supposed to be programmed into MMCRC. However MMCRC is only
+ * HV writable, and there is no API for guest kernels to modify
+ * it. The solution is for the hypervisor to initialise the
+ * field to zeroes, and for us to only ever allow events that
+ * have a cache selector of zero. The bank selector (bit 3) is
+ * irrelevant, as long as the rest of the value is 0.
+ */
+ if (cache & 0x7)
+ return -1;
+
+ } else if (event & EVENT_IS_L1) {
+ mask |= CNST_L1_QUAL_MASK;
+ value |= CNST_L1_QUAL_VAL(cache);
+ }
+
+ if (event & EVENT_IS_MARKED) {
+ mask |= CNST_SAMPLE_MASK;
+ value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT);
+ }
+
+ /*
+ * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC,
+ * the threshold control bits are used for the match value.
+ */
+ if (event_is_fab_match(event)) {
+ mask |= CNST_FAB_MATCH_MASK;
+ value |= CNST_FAB_MATCH_VAL(event >> EVENT_THR_CTL_SHIFT);
+ } else {
+ /*
+ * Check the mantissa upper two bits are not zero, unless the
+ * exponent is also zero. See the THRESH_CMP_MANTISSA doc.
+ */
+ unsigned int cmp, exp;
+
+ cmp = (event >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK;
+ exp = cmp >> 7;
+
+ if (exp && (cmp & 0x60) == 0)
+ return -1;
+
+ mask |= CNST_THRESH_MASK;
+ value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT);
+ }
+
+ if (!pmc && ebb)
+ /* EBB events must specify the PMC */
+ return -1;
+
+ if (event & EVENT_WANTS_BHRB) {
+ if (!ebb)
+ /* Only EBB events can request BHRB */
+ return -1;
+
+ mask |= CNST_IFM_MASK;
+ value |= CNST_IFM_VAL(event >> EVENT_IFM_SHIFT);
+ }
+
+ /*
+ * All events must agree on EBB, either all request it or none.
+ * EBB events are pinned & exclusive, so this should never actually
+ * hit, but we leave it as a fallback in case.
+ */
+ mask |= CNST_EBB_VAL(ebb);
+ value |= CNST_EBB_MASK;
+
+ *maskp = mask;
+ *valp = value;
+
+ return 0;
+}
+
+int isa207_compute_mmcr(u64 event[], int n_ev,
+ unsigned int hwc[], unsigned long mmcr[],
+ struct perf_event *pevents[])
+{
+ unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val;
+ unsigned int pmc, pmc_inuse;
+ int i;
+
+ pmc_inuse = 0;
+
+ /* First pass to count resource use */
+ for (i = 0; i < n_ev; ++i) {
+ pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
+ if (pmc)
+ pmc_inuse |= 1 << pmc;
+ }
+
+ /* In continuous sampling mode, update SDAR on TLB miss */
+ mmcra = MMCRA_SDAR_MODE_TLB;
+ mmcr1 = mmcr2 = 0;
+
+ /* Second pass: assign PMCs, set all MMCR1 fields */
+ for (i = 0; i < n_ev; ++i) {
+ pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
+ unit = (event[i] >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK;
+ combine = (event[i] >> EVENT_COMBINE_SHIFT) & EVENT_COMBINE_MASK;
+ psel = event[i] & EVENT_PSEL_MASK;
+
+ if (!pmc) {
+ for (pmc = 1; pmc <= 4; ++pmc) {
+ if (!(pmc_inuse & (1 << pmc)))
+ break;
+ }
+
+ pmc_inuse |= 1 << pmc;
+ }
+
+ if (pmc <= 4) {
+ mmcr1 |= unit << MMCR1_UNIT_SHIFT(pmc);
+ mmcr1 |= combine << MMCR1_COMBINE_SHIFT(pmc);
+ mmcr1 |= psel << MMCR1_PMCSEL_SHIFT(pmc);
+ }
+
+ if (event[i] & EVENT_IS_L1) {
+ cache = event[i] >> EVENT_CACHE_SEL_SHIFT;
+ mmcr1 |= (cache & 1) << MMCR1_IC_QUAL_SHIFT;
+ cache >>= 1;
+ mmcr1 |= (cache & 1) << MMCR1_DC_QUAL_SHIFT;
+ }
+
+ if (event[i] & EVENT_IS_MARKED) {
+ mmcra |= MMCRA_SAMPLE_ENABLE;
+
+ val = (event[i] >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK;
+ if (val) {
+ mmcra |= (val & 3) << MMCRA_SAMP_MODE_SHIFT;
+ mmcra |= (val >> 2) << MMCRA_SAMP_ELIG_SHIFT;
+ }
+ }
+
+ /*
+ * PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC,
+ * the threshold bits are used for the match value.
+ */
+ if (event_is_fab_match(event[i])) {
+ mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) &
+ EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT;
+ } else {
+ val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK;
+ mmcra |= val << MMCRA_THR_CTL_SHIFT;
+ val = (event[i] >> EVENT_THR_SEL_SHIFT) & EVENT_THR_SEL_MASK;
+ mmcra |= val << MMCRA_THR_SEL_SHIFT;
+ val = (event[i] >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK;
+ mmcra |= val << MMCRA_THR_CMP_SHIFT;
+ }
+
+ if (event[i] & EVENT_WANTS_BHRB) {
+ val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK;
+ mmcra |= val << MMCRA_IFM_SHIFT;
+ }
+
+ if (pevents[i]->attr.exclude_user)
+ mmcr2 |= MMCR2_FCP(pmc);
+
+ if (pevents[i]->attr.exclude_hv)
+ mmcr2 |= MMCR2_FCH(pmc);
+
+ if (pevents[i]->attr.exclude_kernel) {
+ if (cpu_has_feature(CPU_FTR_HVMODE))
+ mmcr2 |= MMCR2_FCH(pmc);
+ else
+ mmcr2 |= MMCR2_FCS(pmc);
+ }
+
+ hwc[i] = pmc - 1;
+ }
+
+ /* Return MMCRx values */
+ mmcr[0] = 0;
+
+ /* pmc_inuse is 1-based */
+ if (pmc_inuse & 2)
+ mmcr[0] = MMCR0_PMC1CE;
+
+ if (pmc_inuse & 0x7c)
+ mmcr[0] |= MMCR0_PMCjCE;
+
+ /* If we're not using PMC 5 or 6, freeze them */
+ if (!(pmc_inuse & 0x60))
+ mmcr[0] |= MMCR0_FC56;
+
+ mmcr[1] = mmcr1;
+ mmcr[2] = mmcra;
+ mmcr[3] = mmcr2;
+
+ return 0;
+}
+
+void isa207_disable_pmc(unsigned int pmc, unsigned long mmcr[])
+{
+ if (pmc <= 3)
+ mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1));
+}
diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h
index 03205f5354e9..4d0a4e5017c2 100644
--- a/arch/powerpc/perf/isa207-common.h
+++ b/arch/powerpc/perf/isa207-common.h
@@ -227,4 +227,10 @@
#define MAX_ALT 2
#define MAX_PMU_COUNTERS 6
+int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp);
+int isa207_compute_mmcr(u64 event[], int n_ev,
+ unsigned int hwc[], unsigned long mmcr[],
+ struct perf_event *pevents[]);
+void isa207_disable_pmc(unsigned int pmc, unsigned long mmcr[]);
+
#endif
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 4303e9b91e43..5fde2b192fec 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -30,250 +30,6 @@ enum {
#define POWER8_MMCRA_IFM2 0x0000000080000000UL
#define POWER8_MMCRA_IFM3 0x00000000C0000000UL
-static inline bool event_is_fab_match(u64 event)
-{
- /* Only check pmc, unit and pmcxsel, ignore the edge bit (0) */
- event &= 0xff0fe;
-
- /* PM_MRK_FAB_RSP_MATCH & PM_MRK_FAB_RSP_MATCH_CYC */
- return (event == 0x30056 || event == 0x4f052);
-}
-
-static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp)
-{
- unsigned int unit, pmc, cache, ebb;
- unsigned long mask, value;
-
- mask = value = 0;
-
- if (event & ~EVENT_VALID_MASK)
- return -1;
-
- pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
- unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK;
- cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK;
- ebb = (event >> EVENT_EBB_SHIFT) & EVENT_EBB_MASK;
-
- if (pmc) {
- u64 base_event;
-
- if (pmc > 6)
- return -1;
-
- /* Ignore Linux defined bits when checking event below */
- base_event = event & ~EVENT_LINUX_MASK;
-
- if (pmc >= 5 && base_event != PM_RUN_INST_CMPL &&
- base_event != PM_RUN_CYC)
- return -1;
-
- mask |= CNST_PMC_MASK(pmc);
- value |= CNST_PMC_VAL(pmc);
- }
-
- if (pmc <= 4) {
- /*
- * Add to number of counters in use. Note this includes events with
- * a PMC of 0 - they still need a PMC, it's just assigned later.
- * Don't count events on PMC 5 & 6, there is only one valid event
- * on each of those counters, and they are handled above.
- */
- mask |= CNST_NC_MASK;
- value |= CNST_NC_VAL;
- }
-
- if (unit >= 6 && unit <= 9) {
- /*
- * L2/L3 events contain a cache selector field, which is
- * supposed to be programmed into MMCRC. However MMCRC is only
- * HV writable, and there is no API for guest kernels to modify
- * it. The solution is for the hypervisor to initialise the
- * field to zeroes, and for us to only ever allow events that
- * have a cache selector of zero. The bank selector (bit 3) is
- * irrelevant, as long as the rest of the value is 0.
- */
- if (cache & 0x7)
- return -1;
-
- } else if (event & EVENT_IS_L1) {
- mask |= CNST_L1_QUAL_MASK;
- value |= CNST_L1_QUAL_VAL(cache);
- }
-
- if (event & EVENT_IS_MARKED) {
- mask |= CNST_SAMPLE_MASK;
- value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT);
- }
-
- /*
- * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC,
- * the threshold control bits are used for the match value.
- */
- if (event_is_fab_match(event)) {
- mask |= CNST_FAB_MATCH_MASK;
- value |= CNST_FAB_MATCH_VAL(event >> EVENT_THR_CTL_SHIFT);
- } else {
- /*
- * Check the mantissa upper two bits are not zero, unless the
- * exponent is also zero. See the THRESH_CMP_MANTISSA doc.
- */
- unsigned int cmp, exp;
-
- cmp = (event >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK;
- exp = cmp >> 7;
-
- if (exp && (cmp & 0x60) == 0)
- return -1;
-
- mask |= CNST_THRESH_MASK;
- value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT);
- }
-
- if (!pmc && ebb)
- /* EBB events must specify the PMC */
- return -1;
-
- if (event & EVENT_WANTS_BHRB) {
- if (!ebb)
- /* Only EBB events can request BHRB */
- return -1;
-
- mask |= CNST_IFM_MASK;
- value |= CNST_IFM_VAL(event >> EVENT_IFM_SHIFT);
- }
-
- /*
- * All events must agree on EBB, either all request it or none.
- * EBB events are pinned & exclusive, so this should never actually
- * hit, but we leave it as a fallback in case.
- */
- mask |= CNST_EBB_VAL(ebb);
- value |= CNST_EBB_MASK;
-
- *maskp = mask;
- *valp = value;
-
- return 0;
-}
-
-static int power8_compute_mmcr(u64 event[], int n_ev,
- unsigned int hwc[], unsigned long mmcr[],
- struct perf_event *pevents[])
-{
- unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val;
- unsigned int pmc, pmc_inuse;
- int i;
-
- pmc_inuse = 0;
-
- /* First pass to count resource use */
- for (i = 0; i < n_ev; ++i) {
- pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
- if (pmc)
- pmc_inuse |= 1 << pmc;
- }
-
- /* In continuous sampling mode, update SDAR on TLB miss */
- mmcra = MMCRA_SDAR_MODE_TLB;
- mmcr1 = mmcr2 = 0;
-
- /* Second pass: assign PMCs, set all MMCR1 fields */
- for (i = 0; i < n_ev; ++i) {
- pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
- unit = (event[i] >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK;
- combine = (event[i] >> EVENT_COMBINE_SHIFT) & EVENT_COMBINE_MASK;
- psel = event[i] & EVENT_PSEL_MASK;
-
- if (!pmc) {
- for (pmc = 1; pmc <= 4; ++pmc) {
- if (!(pmc_inuse & (1 << pmc)))
- break;
- }
-
- pmc_inuse |= 1 << pmc;
- }
-
- if (pmc <= 4) {
- mmcr1 |= unit << MMCR1_UNIT_SHIFT(pmc);
- mmcr1 |= combine << MMCR1_COMBINE_SHIFT(pmc);
- mmcr1 |= psel << MMCR1_PMCSEL_SHIFT(pmc);
- }
-
- if (event[i] & EVENT_IS_L1) {
- cache = event[i] >> EVENT_CACHE_SEL_SHIFT;
- mmcr1 |= (cache & 1) << MMCR1_IC_QUAL_SHIFT;
- cache >>= 1;
- mmcr1 |= (cache & 1) << MMCR1_DC_QUAL_SHIFT;
- }
-
- if (event[i] & EVENT_IS_MARKED) {
- mmcra |= MMCRA_SAMPLE_ENABLE;
-
- val = (event[i] >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK;
- if (val) {
- mmcra |= (val & 3) << MMCRA_SAMP_MODE_SHIFT;
- mmcra |= (val >> 2) << MMCRA_SAMP_ELIG_SHIFT;
- }
- }
-
- /*
- * PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC,
- * the threshold bits are used for the match value.
- */
- if (event_is_fab_match(event[i])) {
- mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) &
- EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT;
- } else {
- val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK;
- mmcra |= val << MMCRA_THR_CTL_SHIFT;
- val = (event[i] >> EVENT_THR_SEL_SHIFT) & EVENT_THR_SEL_MASK;
- mmcra |= val << MMCRA_THR_SEL_SHIFT;
- val = (event[i] >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK;
- mmcra |= val << MMCRA_THR_CMP_SHIFT;
- }
-
- if (event[i] & EVENT_WANTS_BHRB) {
- val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK;
- mmcra |= val << MMCRA_IFM_SHIFT;
- }
-
- if (pevents[i]->attr.exclude_user)
- mmcr2 |= MMCR2_FCP(pmc);
-
- if (pevents[i]->attr.exclude_hv)
- mmcr2 |= MMCR2_FCH(pmc);
-
- if (pevents[i]->attr.exclude_kernel) {
- if (cpu_has_feature(CPU_FTR_HVMODE))
- mmcr2 |= MMCR2_FCH(pmc);
- else
- mmcr2 |= MMCR2_FCS(pmc);
- }
-
- hwc[i] = pmc - 1;
- }
-
- /* Return MMCRx values */
- mmcr[0] = 0;
-
- /* pmc_inuse is 1-based */
- if (pmc_inuse & 2)
- mmcr[0] = MMCR0_PMC1CE;
-
- if (pmc_inuse & 0x7c)
- mmcr[0] |= MMCR0_PMCjCE;
-
- /* If we're not using PMC 5 or 6, freeze them */
- if (!(pmc_inuse & 0x60))
- mmcr[0] |= MMCR0_FC56;
-
- mmcr[1] = mmcr1;
- mmcr[2] = mmcra;
- mmcr[3] = mmcr2;
-
- return 0;
-}
-
/* Table of alternatives, sorted by column 0 */
static const unsigned int event_alternatives[][MAX_ALT] = {
{ PM_MRK_ST_CMPL, PM_MRK_ST_CMPL_ALT },
@@ -354,12 +110,6 @@ static int power8_get_alternatives(u64 event, unsigned int flags, u64 alt[])
return num_alt;
}
-static void power8_disable_pmc(unsigned int pmc, unsigned long mmcr[])
-{
- if (pmc <= 3)
- mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1));
-}
-
GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC);
GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_GCT_NOSLOT_CYC);
GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL);
@@ -632,12 +382,12 @@ static struct power_pmu power8_pmu = {
.max_alternatives = MAX_ALT + 1,
.add_fields = ISA207_ADD_FIELDS,
.test_adder = ISA207_TEST_ADDER,
- .compute_mmcr = power8_compute_mmcr,
+ .compute_mmcr = isa207_compute_mmcr,
.config_bhrb = power8_config_bhrb,
.bhrb_filter_map = power8_bhrb_filter_map,
- .get_constraint = power8_get_constraint,
+ .get_constraint = isa207_get_constraint,
.get_alternatives = power8_get_alternatives,
- .disable_pmc = power8_disable_pmc,
+ .disable_pmc = isa207_disable_pmc,
.flags = PPMU_HAS_SIER | PPMU_ARCH_207S,
.n_generic = ARRAY_SIZE(power8_generic_events),
.generic_events = power8_generic_events,
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/6] powerpc/perf: factor out power8 __init_pmu code
2016-06-26 17:37 [PATCH 1/6] powerpc/perf: factor out power8 pmu macros and defines Madhavan Srinivasan
2016-06-26 17:37 ` [PATCH 2/6] powerpc/perf: factor out power8 pmu functions Madhavan Srinivasan
@ 2016-06-26 17:37 ` Madhavan Srinivasan
2016-06-26 17:37 ` [PATCH 4/6] powerpc/perf: Add power9 event list macros for generic and cache events Madhavan Srinivasan
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Madhavan Srinivasan @ 2016-06-26 17:37 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, Madhavan Srinivasan
Factor out the power8 pmu init functions to share with
power9. Monitor Mode Control Register S(MMCRS) and
Monitor Mode Control Register H(MMCRH) registers are
dropped in Power9. These registers are added to new
function which are included for power8 init.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/kernel/cpu_setup_power.S | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
index 584e119fa8b0..ec8a228df2f6 100644
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -51,6 +51,7 @@ _GLOBAL(__setup_cpu_power8)
mflr r11
bl __init_FSCR
bl __init_PMU
+ bl __init_PMU_ISA207
bl __init_hvmode_206
mtlr r11
beqlr
@@ -62,6 +63,7 @@ _GLOBAL(__setup_cpu_power8)
bl __init_HFSCR
bl __init_tlb_power8
bl __init_PMU_HV
+ bl __init_PMU_HV_ISA207
mtlr r11
blr
@@ -69,6 +71,7 @@ _GLOBAL(__restore_cpu_power8)
mflr r11
bl __init_FSCR
bl __init_PMU
+ bl __init_PMU_ISA207
mfmsr r3
rldicl. r0,r3,4,63
mtlr r11
@@ -81,12 +84,14 @@ _GLOBAL(__restore_cpu_power8)
bl __init_HFSCR
bl __init_tlb_power8
bl __init_PMU_HV
+ bl __init_PMU_HV_ISA207
mtlr r11
blr
_GLOBAL(__setup_cpu_power9)
mflr r11
bl __init_FSCR
+ bl __init_PMU
bl __init_hvmode_206
mtlr r11
beqlr
@@ -97,12 +102,14 @@ _GLOBAL(__setup_cpu_power9)
bl __init_LPCR
bl __init_HFSCR
bl __init_tlb_power9
+ bl __init_PMU_HV
mtlr r11
blr
_GLOBAL(__restore_cpu_power9)
mflr r11
bl __init_FSCR
+ bl __init_PMU
mfmsr r3
rldicl. r0,r3,4,63
mtlr r11
@@ -114,6 +121,7 @@ _GLOBAL(__restore_cpu_power9)
bl __init_LPCR
bl __init_HFSCR
bl __init_tlb_power9
+ bl __init_PMU_HV
mtlr r11
blr
@@ -208,14 +216,22 @@ __init_tlb_power9:
__init_PMU_HV:
li r5,0
mtspr SPRN_MMCRC,r5
+ blr
+
+__init_PMU_HV_ISA207:
+ li r5,0
mtspr SPRN_MMCRH,r5
blr
__init_PMU:
li r5,0
- mtspr SPRN_MMCRS,r5
mtspr SPRN_MMCRA,r5
mtspr SPRN_MMCR0,r5
mtspr SPRN_MMCR1,r5
mtspr SPRN_MMCR2,r5
blr
+
+__init_PMU_ISA207:
+ li r5,0
+ mtspr SPRN_MMCRS,r5
+ blr
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/6] powerpc/perf: Add power9 event list macros for generic and cache events
2016-06-26 17:37 [PATCH 1/6] powerpc/perf: factor out power8 pmu macros and defines Madhavan Srinivasan
2016-06-26 17:37 ` [PATCH 2/6] powerpc/perf: factor out power8 pmu functions Madhavan Srinivasan
2016-06-26 17:37 ` [PATCH 3/6] powerpc/perf: factor out power8 __init_pmu code Madhavan Srinivasan
@ 2016-06-26 17:37 ` Madhavan Srinivasan
2016-06-26 17:37 ` [PATCH 5/6] powerpc/perf: Power9 PMU support Madhavan Srinivasan
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Madhavan Srinivasan @ 2016-06-26 17:37 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, Madhavan Srinivasan
Add macros for the generic and cache events on Power9
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/perf/power9-events-list.h | 55 ++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 arch/powerpc/perf/power9-events-list.h
diff --git a/arch/powerpc/perf/power9-events-list.h b/arch/powerpc/perf/power9-events-list.h
new file mode 100644
index 000000000000..cda6fcb809ca
--- /dev/null
+++ b/arch/powerpc/perf/power9-events-list.h
@@ -0,0 +1,55 @@
+/*
+ * Performance counter support for POWER9 processors.
+ *
+ * Copyright 2016 Madhavan Srinivasan, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * Power9 event codes.
+ */
+EVENT(PM_CYC, 0x0001e)
+EVENT(PM_ICT_NOSLOT_CYC, 0x100f8)
+EVENT(PM_CMPLU_STALL, 0x1e054)
+EVENT(PM_INST_CMPL, 0x00002)
+EVENT(PM_BRU_CMPL, 0x40060)
+EVENT(PM_BR_MPRED_CMPL, 0x400f6)
+
+/* All L1 D cache load references counted at finish, gated by reject */
+EVENT(PM_LD_REF_L1, 0x100fc)
+/* Load Missed L1 */
+EVENT(PM_LD_MISS_L1_FIN, 0x2c04e)
+/* Store Missed L1 */
+EVENT(PM_ST_MISS_L1, 0x300f0)
+/* L1 cache data prefetches */
+EVENT(PM_L1_PREF, 0x20054)
+/* Instruction fetches from L1 */
+EVENT(PM_INST_FROM_L1, 0x04080)
+/* Demand iCache Miss */
+EVENT(PM_L1_ICACHE_MISS, 0x200fd)
+/* Instruction Demand sectors wriittent into IL1 */
+EVENT(PM_L1_DEMAND_WRITE, 0x0408c)
+/* Instruction prefetch written into IL1 */
+EVENT(PM_IC_PREF_WRITE, 0x0408e)
+/* The data cache was reloaded from local core's L3 due to a demand load */
+EVENT(PM_DATA_FROM_L3, 0x4c042)
+/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */
+EVENT(PM_DATA_FROM_L3MISS, 0x300fe)
+/* All successful D-side store dispatches for this thread */
+EVENT(PM_L2_ST, 0x16081)
+/* All successful D-side store dispatches for this thread that were L2 Miss */
+EVENT(PM_L2_ST_MISS, 0x26081)
+/* Total HW L3 prefetches(Load+store) */
+EVENT(PM_L3_PREF_ALL, 0x4e052)
+/* Data PTEG reload */
+EVENT(PM_DTLB_MISS, 0x300fc)
+/* ITLB Reloaded */
+EVENT(PM_ITLB_MISS, 0x400fc)
+/* Run_Instructions */
+EVENT(PM_RUN_INST_CMPL, 0x500fa)
+/* Run_cycles */
+EVENT(PM_RUN_CYC, 0x600f4)
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/6] powerpc/perf: Power9 PMU support
2016-06-26 17:37 [PATCH 1/6] powerpc/perf: factor out power8 pmu macros and defines Madhavan Srinivasan
` (2 preceding siblings ...)
2016-06-26 17:37 ` [PATCH 4/6] powerpc/perf: Add power9 event list macros for generic and cache events Madhavan Srinivasan
@ 2016-06-26 17:37 ` Madhavan Srinivasan
2016-07-05 1:00 ` Michael Neuling
2016-06-26 17:37 ` [PATCH 6/6] powerpc/perf: Export Power9 generic and cache events to sysfs Madhavan Srinivasan
2016-07-05 14:10 ` [1/6] powerpc/perf: factor out power8 pmu macros and defines Michael Ellerman
5 siblings, 1 reply; 9+ messages in thread
From: Madhavan Srinivasan @ 2016-06-26 17:37 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, Madhavan Srinivasan
This patch adds base enablement for the power9 PMU.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/perf/Makefile | 2 +-
arch/powerpc/perf/power9-pmu.c | 271 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 272 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/perf/power9-pmu.c
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 92f8ea46238b..f102d5370101 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o
obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \
power5+-pmu.o power6-pmu.o power7-pmu.o \
- isa207-common.o power8-pmu.o
+ isa207-common.o power8-pmu.o power9-pmu.o
obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
diff --git a/arch/powerpc/perf/power9-pmu.c b/arch/powerpc/perf/power9-pmu.c
new file mode 100644
index 000000000000..a2798b5915b9
--- /dev/null
+++ b/arch/powerpc/perf/power9-pmu.c
@@ -0,0 +1,271 @@
+/*
+ * Performance counter support for POWER9 processors.
+ *
+ * Copyright 2009 Paul Mackerras, IBM Corporation.
+ * Copyright 2013 Michael Ellerman, IBM Corporation.
+ * Copyright 2016 Madhavan Srinivasan, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or later version.
+ */
+
+#define pr_fmt(fmt) "power9-pmu: " fmt
+
+#include "isa207-common.h"
+
+/*
+ * Some power9 event codes.
+ */
+#define EVENT(_name, _code) _name = _code,
+
+enum {
+#include "power9-events-list.h"
+};
+
+#undef EVENT
+
+/* MMCRA IFM bits - POWER9 */
+#define POWER9_MMCRA_IFM1 0x0000000040000000UL
+#define POWER9_MMCRA_IFM2 0x0000000080000000UL
+#define POWER9_MMCRA_IFM3 0x00000000C0000000UL
+
+
+PMU_FORMAT_ATTR(event, "config:0-49");
+PMU_FORMAT_ATTR(pmcxsel, "config:0-7");
+PMU_FORMAT_ATTR(mark, "config:8");
+PMU_FORMAT_ATTR(combine, "config:11");
+PMU_FORMAT_ATTR(unit, "config:12-15");
+PMU_FORMAT_ATTR(pmc, "config:16-19");
+PMU_FORMAT_ATTR(cache_sel, "config:20-23");
+PMU_FORMAT_ATTR(sample_mode, "config:24-28");
+PMU_FORMAT_ATTR(thresh_sel, "config:29-31");
+PMU_FORMAT_ATTR(thresh_stop, "config:32-35");
+PMU_FORMAT_ATTR(thresh_start, "config:36-39");
+PMU_FORMAT_ATTR(thresh_cmp, "config:40-49");
+
+static struct attribute *power9_pmu_format_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_pmcxsel.attr,
+ &format_attr_mark.attr,
+ &format_attr_combine.attr,
+ &format_attr_unit.attr,
+ &format_attr_pmc.attr,
+ &format_attr_cache_sel.attr,
+ &format_attr_sample_mode.attr,
+ &format_attr_thresh_sel.attr,
+ &format_attr_thresh_stop.attr,
+ &format_attr_thresh_start.attr,
+ &format_attr_thresh_cmp.attr,
+ NULL,
+};
+
+struct attribute_group power9_pmu_format_group = {
+ .name = "format",
+ .attrs = power9_pmu_format_attr,
+};
+
+static const struct attribute_group *power9_pmu_attr_groups[] = {
+ &power9_pmu_format_group,
+ NULL,
+};
+
+static int power9_generic_events[] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_ICT_NOSLOT_CYC,
+ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL,
+ [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_CMPL,
+ [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1,
+ [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1_FIN,
+};
+
+static u64 power9_bhrb_filter_map(u64 branch_sample_type)
+{
+ u64 pmu_bhrb_filter = 0;
+
+ /* BHRB and regular PMU events share the same privilege state
+ * filter configuration. BHRB is always recorded along with a
+ * regular PMU event. As the privilege state filter is handled
+ * in the basic PMC configuration of the accompanying regular
+ * PMU event, we ignore any separate BHRB specific request.
+ */
+
+ /* No branch filter requested */
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY)
+ return pmu_bhrb_filter;
+
+ /* Invalid branch filter options - HW does not support */
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
+ return -1;
+
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
+ return -1;
+
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_CALL)
+ return -1;
+
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
+ pmu_bhrb_filter |= POWER9_MMCRA_IFM1;
+ return pmu_bhrb_filter;
+ }
+
+ /* Every thing else is unsupported */
+ return -1;
+}
+
+static void power9_config_bhrb(u64 pmu_bhrb_filter)
+{
+ /* Enable BHRB filter in PMU */
+ mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
+}
+
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+/*
+ * Table of generalized cache-related events.
+ * 0 means not supported, -1 means nonsensical, other values
+ * are event codes.
+ */
+static int power9_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = PM_LD_REF_L1,
+ [ C(RESULT_MISS) ] = PM_LD_MISS_L1_FIN,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = PM_ST_MISS_L1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = PM_L1_PREF,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(L1I) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = PM_INST_FROM_L1,
+ [ C(RESULT_MISS) ] = PM_L1_ICACHE_MISS,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = PM_L1_DEMAND_WRITE,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = PM_IC_PREF_WRITE,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(LL) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = PM_DATA_FROM_L3,
+ [ C(RESULT_MISS) ] = PM_DATA_FROM_L3MISS,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = PM_L2_ST,
+ [ C(RESULT_MISS) ] = PM_L2_ST_MISS,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = PM_L3_PREF_ALL,
+ [ C(RESULT_MISS) ] = 0,
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = PM_DTLB_MISS,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = PM_ITLB_MISS,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = PM_BRU_CMPL,
+ [ C(RESULT_MISS) ] = PM_BR_MPRED_CMPL,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+#undef C
+
+static struct power_pmu power9_pmu = {
+ .name = "POWER9",
+ .n_counter = MAX_PMU_COUNTERS,
+ .add_fields = ISA207_ADD_FIELDS,
+ .test_adder = ISA207_TEST_ADDER,
+ .compute_mmcr = isa207_compute_mmcr,
+ .config_bhrb = power9_config_bhrb,
+ .bhrb_filter_map = power9_bhrb_filter_map,
+ .get_constraint = isa207_get_constraint,
+ .disable_pmc = isa207_disable_pmc,
+ .flags = PPMU_HAS_SIER | PPMU_ARCH_207S,
+ .n_generic = ARRAY_SIZE(power9_generic_events),
+ .generic_events = power9_generic_events,
+ .cache_events = &power9_cache_events,
+ .attr_groups = power9_pmu_attr_groups,
+ .bhrb_nr = 32,
+};
+
+static int __init init_power9_pmu(void)
+{
+ int rc;
+
+ /* Comes from cpu_specs[] */
+ if (!cur_cpu_spec->oprofile_cpu_type ||
+ strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power9"))
+ return -ENODEV;
+
+ rc = register_power_pmu(&power9_pmu);
+ if (rc)
+ return rc;
+
+ /* Tell userspace that EBB is supported */
+ cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
+
+ return 0;
+}
+early_initcall(init_power9_pmu);
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 5/6] powerpc/perf: Power9 PMU support
2016-06-26 17:37 ` [PATCH 5/6] powerpc/perf: Power9 PMU support Madhavan Srinivasan
@ 2016-07-05 1:00 ` Michael Neuling
2016-07-05 4:05 ` Madhavan Srinivasan
0 siblings, 1 reply; 9+ messages in thread
From: Michael Neuling @ 2016-07-05 1:00 UTC (permalink / raw)
To: Madhavan Srinivasan, mpe; +Cc: linuxppc-dev
On Sun, 2016-06-26 at 23:07 +0530, Madhavan Srinivasan wrote:
>=20
There is still identical code here between power8 and power9. Any reason
you can't merge these too? =C2=A0The two bhrb functions seem to be the same=
.
Mikey
> This patch adds base enablement for the power9 PMU.
>=20
> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> ---
> =C2=A0arch/powerpc/perf/Makefile=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0|=C2=A0=C2=
=A0=C2=A02 +-
> =C2=A0arch/powerpc/perf/power9-pmu.c | 271 ++++++++++++++++++++++++++++++=
+++++++++++
> =C2=A02 files changed, 272 insertions(+), 1 deletion(-)
> =C2=A0create mode 100644 arch/powerpc/perf/power9-pmu.c
>=20
> diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
> index 92f8ea46238b..f102d5370101 100644
> --- a/arch/powerpc/perf/Makefile
> +++ b/arch/powerpc/perf/Makefile
> @@ -5,7 +5,7 @@ obj-$(CONFIG_PERF_EVENTS) +=3D callchain.o perf_regs.o
> =C2=A0obj-$(CONFIG_PPC_PERF_CTRS) +=3D core-book3s.o bhrb.o
> =C2=A0obj64-$(CONFIG_PPC_PERF_CTRS) +=3D power4-pmu.o ppc970-pmu.o power5=
-pmu.o \
> =C2=A0 =C2=A0=C2=A0=C2=A0power5+-pmu.o power6-pmu.o power7-pmu.o \
> - =C2=A0=C2=A0=C2=A0isa207-common.o power8-pmu.o
> + =C2=A0=C2=A0=C2=A0isa207-common.o power8-pmu.o power9-pmu.o
> =C2=A0obj32-$(CONFIG_PPC_PERF_CTRS) +=3D mpc7450-pmu.o
> =C2=A0
> =C2=A0obj-$(CONFIG_FSL_EMB_PERF_EVENT) +=3D core-fsl-emb.o
> diff --git a/arch/powerpc/perf/power9-pmu.c b/arch/powerpc/perf/power9-pm=
u.c
> new file mode 100644
> index 000000000000..a2798b5915b9
> --- /dev/null
> +++ b/arch/powerpc/perf/power9-pmu.c
> @@ -0,0 +1,271 @@
> +/*
> + * Performance counter support for POWER9 processors.
> + *
> + * Copyright 2009 Paul Mackerras, IBM Corporation.
> + * Copyright 2013 Michael Ellerman, IBM Corporation.
> + * Copyright 2016 Madhavan Srinivasan, IBM Corporation.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or later version.
> + */
> +
> +#define pr_fmt(fmt) "power9-pmu: " fmt
> +
> +#include "isa207-common.h"
> +
> +/*
> + * Some power9 event codes.
> + */
> +#define EVENT(_name, _code) _name =3D _code,
> +
> +enum {
> +#include "power9-events-list.h"
> +};
> +
> +#undef EVENT
> +
> +/* MMCRA IFM bits - POWER9 */
> +#define POWER9_MMCRA_IFM1 0x0000000040000000UL
> +#define POWER9_MMCRA_IFM2 0x0000000080000000UL
> +#define POWER9_MMCRA_IFM3 0x00000000C0000000UL
> +
> +
> +PMU_FORMAT_ATTR(event, "config:0-49");
> +PMU_FORMAT_ATTR(pmcxsel, "config:0-7");
> +PMU_FORMAT_ATTR(mark, "config:8");
> +PMU_FORMAT_ATTR(combine, "config:11");
> +PMU_FORMAT_ATTR(unit, "config:12-15");
> +PMU_FORMAT_ATTR(pmc, "config:16-19");
> +PMU_FORMAT_ATTR(cache_sel, "config:20-23");
> +PMU_FORMAT_ATTR(sample_mode, "config:24-28");
> +PMU_FORMAT_ATTR(thresh_sel, "config:29-31");
> +PMU_FORMAT_ATTR(thresh_stop, "config:32-35");
> +PMU_FORMAT_ATTR(thresh_start, "config:36-39");
> +PMU_FORMAT_ATTR(thresh_cmp, "config:40-49");
> +
> +static struct attribute *power9_pmu_format_attr[] =3D {
> + &format_attr_event.attr,
> + &format_attr_pmcxsel.attr,
> + &format_attr_mark.attr,
> + &format_attr_combine.attr,
> + &format_attr_unit.attr,
> + &format_attr_pmc.attr,
> + &format_attr_cache_sel.attr,
> + &format_attr_sample_mode.attr,
> + &format_attr_thresh_sel.attr,
> + &format_attr_thresh_stop.attr,
> + &format_attr_thresh_start.attr,
> + &format_attr_thresh_cmp.attr,
> + NULL,
> +};
> +
> +struct attribute_group power9_pmu_format_group =3D {
> + .name =3D "format",
> + .attrs =3D power9_pmu_format_attr,
> +};
> +
> +static const struct attribute_group *power9_pmu_attr_groups[] =3D {
> + &power9_pmu_format_group,
> + NULL,
> +};
> +
> +static int power9_generic_events[] =3D {
> + [PERF_COUNT_HW_CPU_CYCLES] =3D PM_CYC,
> + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =3D PM_ICT_NOSLOT_CYC,
> + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =3D PM_CMPLU_STALL,
> + [PERF_COUNT_HW_INSTRUCTIONS] =3D PM_INST_CMPL,
> + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =3D PM_BRU_CMPL,
> + [PERF_COUNT_HW_BRANCH_MISSES] =3D PM_BR_MPRED_CMPL,
> + [PERF_COUNT_HW_CACHE_REFERENCES] =3D PM_LD_REF_L1,
> + [PERF_COUNT_HW_CACHE_MISSES] =3D PM_LD_MISS_L1_FIN,
> +};
> +
> +static u64 power9_bhrb_filter_map(u64 branch_sample_type)
> +{
> + u64 pmu_bhrb_filter =3D 0;
> +
> + /* BHRB and regular PMU events share the same privilege state
> + =C2=A0* filter configuration. BHRB is always recorded along with a
> + =C2=A0* regular PMU event. As the privilege state filter is handled
> + =C2=A0* in the basic PMC configuration of the accompanying regular
> + =C2=A0* PMU event, we ignore any separate BHRB specific request.
> + =C2=A0*/
> +
> + /* No branch filter requested */
> + if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY)
> + return pmu_bhrb_filter;
> +
> + /* Invalid branch filter options - HW does not support */
> + if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
> + return -1;
> +
> + if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
> + return -1;
> +
> + if (branch_sample_type & PERF_SAMPLE_BRANCH_CALL)
> + return -1;
> +
> + if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
> + pmu_bhrb_filter |=3D POWER9_MMCRA_IFM1;
> + return pmu_bhrb_filter;
> + }
> +
> + /* Every thing else is unsupported */
> + return -1;
> +}
> +static void power9_config_bhrb(u64 pmu_bhrb_filter)
> +{
> + /* Enable BHRB filter in PMU */
> + mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
> +}
Same here.
> +#define C(x) PERF_COUNT_HW_CACHE_##x
> +
> +/*
> + * Table of generalized cache-related events.
> + * 0 means not supported, -1 means nonsensical, other values
> + * are event codes.
> + */
> +static int power9_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] =3D {
> + [ C(L1D) ] =3D {
> + [ C(OP_READ) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_LD_REF_L1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D PM_LD_MISS_L1_FIN,
> + },
> + [ C(OP_WRITE) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D 0,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D PM_ST_MISS_L1,
> + },
> + [ C(OP_PREFETCH) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_L1_PREF,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D 0,
> + },
> + },
> + [ C(L1I) ] =3D {
> + [ C(OP_READ) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_INST_FROM_L1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D PM_L1_ICACHE_MISS,
> + },
> + [ C(OP_WRITE) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_L1_DEMAND_WRITE,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + [ C(OP_PREFETCH) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_IC_PREF_WRITE,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D 0,
> + },
> + },
> + [ C(LL) ] =3D {
> + [ C(OP_READ) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_DATA_FROM_L3,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D PM_DATA_FROM_L3MISS,
> + },
> + [ C(OP_WRITE) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_L2_ST,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D PM_L2_ST_MISS,
> + },
> + [ C(OP_PREFETCH) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_L3_PREF_ALL,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D 0,
> + },
> + },
> + [ C(DTLB) ] =3D {
> + [ C(OP_READ) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D 0,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D PM_DTLB_MISS,
> + },
> + [ C(OP_WRITE) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + [ C(OP_PREFETCH) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + },
> + [ C(ITLB) ] =3D {
> + [ C(OP_READ) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D 0,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D PM_ITLB_MISS,
> + },
> + [ C(OP_WRITE) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + [ C(OP_PREFETCH) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + },
> + [ C(BPU) ] =3D {
> + [ C(OP_READ) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D PM_BRU_CMPL,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D PM_BR_MPRED_CMPL,
> + },
> + [ C(OP_WRITE) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + [ C(OP_PREFETCH) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + },
> + [ C(NODE) ] =3D {
> + [ C(OP_READ) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + [ C(OP_WRITE) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + [ C(OP_PREFETCH) ] =3D {
> + [ C(RESULT_ACCESS) ] =3D -1,
> + [ C(RESULT_MISS)=C2=A0=C2=A0=C2=A0] =3D -1,
> + },
> + },
> +};
> +
> +#undef C
> +
> +static struct power_pmu power9_pmu =3D {
> + .name =3D "POWER9",
> + .n_counter =3D MAX_PMU_COUNTERS,
> + .add_fields =3D ISA207_ADD_FIELDS,
> + .test_adder =3D ISA207_TEST_ADDER,
> + .compute_mmcr =3D isa207_compute_mmcr,
> + .config_bhrb =3D power9_config_bhrb,
> + .bhrb_filter_map =3D power9_bhrb_filter_map,
> + .get_constraint =3D isa207_get_constraint,
> + .disable_pmc =3D isa207_disable_pmc,
> + .flags =3D PPMU_HAS_SIER | PPMU_ARCH_207S,
> + .n_generic =3D ARRAY_SIZE(power9_generic_events),
> + .generic_events =3D power9_generic_events,
> + .cache_events =3D &power9_cache_events,
> + .attr_groups =3D power9_pmu_attr_groups,
> + .bhrb_nr =3D 32,
> +};
> +
> +static int __init init_power9_pmu(void)
> +{
> + int rc;
> +
> + /* Comes from cpu_specs[] */
> + if (!cur_cpu_spec->oprofile_cpu_type ||
> + =C2=A0=C2=A0=C2=A0=C2=A0strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/=
power9"))
> + return -ENODEV;
> +
> + rc =3D register_power_pmu(&power9_pmu);
> + if (rc)
> + return rc;
> +
> + /* Tell userspace that EBB is supported */
> + cur_cpu_spec->cpu_user_features2 |=3D PPC_FEATURE2_EBB;
> +
> + return 0;
> +}
> +early_initcall(init_power9_pmu);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 5/6] powerpc/perf: Power9 PMU support
2016-07-05 1:00 ` Michael Neuling
@ 2016-07-05 4:05 ` Madhavan Srinivasan
0 siblings, 0 replies; 9+ messages in thread
From: Madhavan Srinivasan @ 2016-07-05 4:05 UTC (permalink / raw)
To: Michael Neuling, mpe; +Cc: linuxppc-dev
On Tuesday 05 July 2016 06:30 AM, Michael Neuling wrote:
> On Sun, 2016-06-26 at 23:07 +0530, Madhavan Srinivasan wrote:
>
> There is still identical code here between power8 and power9. Any reason
> you can't merge these too? The two bhrb functions seem to be the same.
In PowerISA v3.0, more bhrb filtering modes are added. And if made common,
we need to have checks for these new filtering mode which can be avoided.
Yes, right now its the same code, but will post the power9 bhrb filtering
mode patches soon.
Maddy
>
> Mikey
>
>> This patch adds base enablement for the power9 PMU.
>>
>> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>> ---
>> arch/powerpc/perf/Makefile | 2 +-
>> arch/powerpc/perf/power9-pmu.c | 271 +++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 272 insertions(+), 1 deletion(-)
>> create mode 100644 arch/powerpc/perf/power9-pmu.c
>>
>> diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
>> index 92f8ea46238b..f102d5370101 100644
>> --- a/arch/powerpc/perf/Makefile
>> +++ b/arch/powerpc/perf/Makefile
>> @@ -5,7 +5,7 @@ obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o
>> obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
>> obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \
>> power5+-pmu.o power6-pmu.o power7-pmu.o \
>> - isa207-common.o power8-pmu.o
>> + isa207-common.o power8-pmu.o power9-pmu.o
>> obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
>>
>> obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
>> diff --git a/arch/powerpc/perf/power9-pmu.c b/arch/powerpc/perf/power9-pmu.c
>> new file mode 100644
>> index 000000000000..a2798b5915b9
>> --- /dev/null
>> +++ b/arch/powerpc/perf/power9-pmu.c
>> @@ -0,0 +1,271 @@
>> +/*
>> + * Performance counter support for POWER9 processors.
>> + *
>> + * Copyright 2009 Paul Mackerras, IBM Corporation.
>> + * Copyright 2013 Michael Ellerman, IBM Corporation.
>> + * Copyright 2016 Madhavan Srinivasan, IBM Corporation.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version
>> + * 2 of the License, or later version.
>> + */
>> +
>> +#define pr_fmt(fmt) "power9-pmu: " fmt
>> +
>> +#include "isa207-common.h"
>> +
>> +/*
>> + * Some power9 event codes.
>> + */
>> +#define EVENT(_name, _code) _name = _code,
>> +
>> +enum {
>> +#include "power9-events-list.h"
>> +};
>> +
>> +#undef EVENT
>> +
>> +/* MMCRA IFM bits - POWER9 */
>> +#define POWER9_MMCRA_IFM1 0x0000000040000000UL
>> +#define POWER9_MMCRA_IFM2 0x0000000080000000UL
>> +#define POWER9_MMCRA_IFM3 0x00000000C0000000UL
>> +
>> +
>> +PMU_FORMAT_ATTR(event, "config:0-49");
>> +PMU_FORMAT_ATTR(pmcxsel, "config:0-7");
>> +PMU_FORMAT_ATTR(mark, "config:8");
>> +PMU_FORMAT_ATTR(combine, "config:11");
>> +PMU_FORMAT_ATTR(unit, "config:12-15");
>> +PMU_FORMAT_ATTR(pmc, "config:16-19");
>> +PMU_FORMAT_ATTR(cache_sel, "config:20-23");
>> +PMU_FORMAT_ATTR(sample_mode, "config:24-28");
>> +PMU_FORMAT_ATTR(thresh_sel, "config:29-31");
>> +PMU_FORMAT_ATTR(thresh_stop, "config:32-35");
>> +PMU_FORMAT_ATTR(thresh_start, "config:36-39");
>> +PMU_FORMAT_ATTR(thresh_cmp, "config:40-49");
>> +
>> +static struct attribute *power9_pmu_format_attr[] = {
>> + &format_attr_event.attr,
>> + &format_attr_pmcxsel.attr,
>> + &format_attr_mark.attr,
>> + &format_attr_combine.attr,
>> + &format_attr_unit.attr,
>> + &format_attr_pmc.attr,
>> + &format_attr_cache_sel.attr,
>> + &format_attr_sample_mode.attr,
>> + &format_attr_thresh_sel.attr,
>> + &format_attr_thresh_stop.attr,
>> + &format_attr_thresh_start.attr,
>> + &format_attr_thresh_cmp.attr,
>> + NULL,
>> +};
>> +
>> +struct attribute_group power9_pmu_format_group = {
>> + .name = "format",
>> + .attrs = power9_pmu_format_attr,
>> +};
>> +
>> +static const struct attribute_group *power9_pmu_attr_groups[] = {
>> + &power9_pmu_format_group,
>> + NULL,
>> +};
>> +
>> +static int power9_generic_events[] = {
>> + [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,
>> + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_ICT_NOSLOT_CYC,
>> + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL,
>> + [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,
>> + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_CMPL,
>> + [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL,
>> + [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1,
>> + [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1_FIN,
>> +};
>> +
>> +static u64 power9_bhrb_filter_map(u64 branch_sample_type)
>> +{
>> + u64 pmu_bhrb_filter = 0;
>> +
>> + /* BHRB and regular PMU events share the same privilege state
>> + * filter configuration. BHRB is always recorded along with a
>> + * regular PMU event. As the privilege state filter is handled
>> + * in the basic PMC configuration of the accompanying regular
>> + * PMU event, we ignore any separate BHRB specific request.
>> + */
>> +
>> + /* No branch filter requested */
>> + if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY)
>> + return pmu_bhrb_filter;
>> +
>> + /* Invalid branch filter options - HW does not support */
>> + if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
>> + return -1;
>> +
>> + if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
>> + return -1;
>> +
>> + if (branch_sample_type & PERF_SAMPLE_BRANCH_CALL)
>> + return -1;
>> +
>> + if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
>> + pmu_bhrb_filter |= POWER9_MMCRA_IFM1;
>> + return pmu_bhrb_filter;
>> + }
>> +
>> + /* Every thing else is unsupported */
>> + return -1;
>> +}
>> +static void power9_config_bhrb(u64 pmu_bhrb_filter)
>> +{
>> + /* Enable BHRB filter in PMU */
>> + mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
>> +}
> Same here.
>
>> +#define C(x) PERF_COUNT_HW_CACHE_##x
>> +
>> +/*
>> + * Table of generalized cache-related events.
>> + * 0 means not supported, -1 means nonsensical, other values
>> + * are event codes.
>> + */
>> +static int power9_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
>> + [ C(L1D) ] = {
>> + [ C(OP_READ) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_LD_REF_L1,
>> + [ C(RESULT_MISS) ] = PM_LD_MISS_L1_FIN,
>> + },
>> + [ C(OP_WRITE) ] = {
>> + [ C(RESULT_ACCESS) ] = 0,
>> + [ C(RESULT_MISS) ] = PM_ST_MISS_L1,
>> + },
>> + [ C(OP_PREFETCH) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_L1_PREF,
>> + [ C(RESULT_MISS) ] = 0,
>> + },
>> + },
>> + [ C(L1I) ] = {
>> + [ C(OP_READ) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_INST_FROM_L1,
>> + [ C(RESULT_MISS) ] = PM_L1_ICACHE_MISS,
>> + },
>> + [ C(OP_WRITE) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_L1_DEMAND_WRITE,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + [ C(OP_PREFETCH) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_IC_PREF_WRITE,
>> + [ C(RESULT_MISS) ] = 0,
>> + },
>> + },
>> + [ C(LL) ] = {
>> + [ C(OP_READ) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_DATA_FROM_L3,
>> + [ C(RESULT_MISS) ] = PM_DATA_FROM_L3MISS,
>> + },
>> + [ C(OP_WRITE) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_L2_ST,
>> + [ C(RESULT_MISS) ] = PM_L2_ST_MISS,
>> + },
>> + [ C(OP_PREFETCH) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_L3_PREF_ALL,
>> + [ C(RESULT_MISS) ] = 0,
>> + },
>> + },
>> + [ C(DTLB) ] = {
>> + [ C(OP_READ) ] = {
>> + [ C(RESULT_ACCESS) ] = 0,
>> + [ C(RESULT_MISS) ] = PM_DTLB_MISS,
>> + },
>> + [ C(OP_WRITE) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + [ C(OP_PREFETCH) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + },
>> + [ C(ITLB) ] = {
>> + [ C(OP_READ) ] = {
>> + [ C(RESULT_ACCESS) ] = 0,
>> + [ C(RESULT_MISS) ] = PM_ITLB_MISS,
>> + },
>> + [ C(OP_WRITE) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + [ C(OP_PREFETCH) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + },
>> + [ C(BPU) ] = {
>> + [ C(OP_READ) ] = {
>> + [ C(RESULT_ACCESS) ] = PM_BRU_CMPL,
>> + [ C(RESULT_MISS) ] = PM_BR_MPRED_CMPL,
>> + },
>> + [ C(OP_WRITE) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + [ C(OP_PREFETCH) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + },
>> + [ C(NODE) ] = {
>> + [ C(OP_READ) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + [ C(OP_WRITE) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + [ C(OP_PREFETCH) ] = {
>> + [ C(RESULT_ACCESS) ] = -1,
>> + [ C(RESULT_MISS) ] = -1,
>> + },
>> + },
>> +};
>> +
>> +#undef C
>> +
>> +static struct power_pmu power9_pmu = {
>> + .name = "POWER9",
>> + .n_counter = MAX_PMU_COUNTERS,
>> + .add_fields = ISA207_ADD_FIELDS,
>> + .test_adder = ISA207_TEST_ADDER,
>> + .compute_mmcr = isa207_compute_mmcr,
>> + .config_bhrb = power9_config_bhrb,
>> + .bhrb_filter_map = power9_bhrb_filter_map,
>> + .get_constraint = isa207_get_constraint,
>> + .disable_pmc = isa207_disable_pmc,
>> + .flags = PPMU_HAS_SIER | PPMU_ARCH_207S,
>> + .n_generic = ARRAY_SIZE(power9_generic_events),
>> + .generic_events = power9_generic_events,
>> + .cache_events = &power9_cache_events,
>> + .attr_groups = power9_pmu_attr_groups,
>> + .bhrb_nr = 32,
>> +};
>> +
>> +static int __init init_power9_pmu(void)
>> +{
>> + int rc;
>> +
>> + /* Comes from cpu_specs[] */
>> + if (!cur_cpu_spec->oprofile_cpu_type ||
>> + strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power9"))
>> + return -ENODEV;
>> +
>> + rc = register_power_pmu(&power9_pmu);
>> + if (rc)
>> + return rc;
>> +
>> + /* Tell userspace that EBB is supported */
>> + cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
>> +
>> + return 0;
>> +}
>> +early_initcall(init_power9_pmu);
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 6/6] powerpc/perf: Export Power9 generic and cache events to sysfs
2016-06-26 17:37 [PATCH 1/6] powerpc/perf: factor out power8 pmu macros and defines Madhavan Srinivasan
` (3 preceding siblings ...)
2016-06-26 17:37 ` [PATCH 5/6] powerpc/perf: Power9 PMU support Madhavan Srinivasan
@ 2016-06-26 17:37 ` Madhavan Srinivasan
2016-07-05 14:10 ` [1/6] powerpc/perf: factor out power8 pmu macros and defines Michael Ellerman
5 siblings, 0 replies; 9+ messages in thread
From: Madhavan Srinivasan @ 2016-06-26 17:37 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, Madhavan Srinivasan
Export the generic hardware and cache perf events for Power9 to sysfs,
so users can determine the PMU event monitored.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/perf/power9-pmu.c | 59 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/arch/powerpc/perf/power9-pmu.c b/arch/powerpc/perf/power9-pmu.c
index a2798b5915b9..788346303852 100644
--- a/arch/powerpc/perf/power9-pmu.c
+++ b/arch/powerpc/perf/power9-pmu.c
@@ -31,6 +31,64 @@ enum {
#define POWER9_MMCRA_IFM2 0x0000000080000000UL
#define POWER9_MMCRA_IFM3 0x00000000C0000000UL
+GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC);
+GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_ICT_NOSLOT_CYC);
+GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL);
+GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL);
+GENERIC_EVENT_ATTR(branch-instructions, PM_BRU_CMPL);
+GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL);
+GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1);
+GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1_FIN);
+
+CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1_FIN);
+CACHE_EVENT_ATTR(L1-dcache-loads, PM_LD_REF_L1);
+CACHE_EVENT_ATTR(L1-dcache-prefetches, PM_L1_PREF);
+CACHE_EVENT_ATTR(L1-dcache-store-misses, PM_ST_MISS_L1);
+CACHE_EVENT_ATTR(L1-icache-load-misses, PM_L1_ICACHE_MISS);
+CACHE_EVENT_ATTR(L1-icache-loads, PM_INST_FROM_L1);
+CACHE_EVENT_ATTR(L1-icache-prefetches, PM_IC_PREF_WRITE);
+CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS);
+CACHE_EVENT_ATTR(LLC-loads, PM_DATA_FROM_L3);
+CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PREF_ALL);
+CACHE_EVENT_ATTR(LLC-store-misses, PM_L2_ST_MISS);
+CACHE_EVENT_ATTR(LLC-stores, PM_L2_ST);
+CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL);
+CACHE_EVENT_ATTR(branch-loads, PM_BRU_CMPL);
+CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS);
+CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS);
+
+static struct attribute *power9_events_attr[] = {
+ GENERIC_EVENT_PTR(PM_CYC),
+ GENERIC_EVENT_PTR(PM_ICT_NOSLOT_CYC),
+ GENERIC_EVENT_PTR(PM_CMPLU_STALL),
+ GENERIC_EVENT_PTR(PM_INST_CMPL),
+ GENERIC_EVENT_PTR(PM_BRU_CMPL),
+ GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL),
+ GENERIC_EVENT_PTR(PM_LD_REF_L1),
+ GENERIC_EVENT_PTR(PM_LD_MISS_L1_FIN),
+ CACHE_EVENT_PTR(PM_LD_MISS_L1_FIN),
+ CACHE_EVENT_PTR(PM_LD_REF_L1),
+ CACHE_EVENT_PTR(PM_L1_PREF),
+ CACHE_EVENT_PTR(PM_ST_MISS_L1),
+ CACHE_EVENT_PTR(PM_L1_ICACHE_MISS),
+ CACHE_EVENT_PTR(PM_INST_FROM_L1),
+ CACHE_EVENT_PTR(PM_IC_PREF_WRITE),
+ CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS),
+ CACHE_EVENT_PTR(PM_DATA_FROM_L3),
+ CACHE_EVENT_PTR(PM_L3_PREF_ALL),
+ CACHE_EVENT_PTR(PM_L2_ST_MISS),
+ CACHE_EVENT_PTR(PM_L2_ST),
+ CACHE_EVENT_PTR(PM_BR_MPRED_CMPL),
+ CACHE_EVENT_PTR(PM_BRU_CMPL),
+ CACHE_EVENT_PTR(PM_DTLB_MISS),
+ CACHE_EVENT_PTR(PM_ITLB_MISS),
+ NULL
+};
+
+static struct attribute_group power9_pmu_events_group = {
+ .name = "events",
+ .attrs = power9_events_attr,
+};
PMU_FORMAT_ATTR(event, "config:0-49");
PMU_FORMAT_ATTR(pmcxsel, "config:0-7");
@@ -68,6 +126,7 @@ struct attribute_group power9_pmu_format_group = {
static const struct attribute_group *power9_pmu_attr_groups[] = {
&power9_pmu_format_group,
+ &power9_pmu_events_group,
NULL,
};
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [1/6] powerpc/perf: factor out power8 pmu macros and defines
2016-06-26 17:37 [PATCH 1/6] powerpc/perf: factor out power8 pmu macros and defines Madhavan Srinivasan
` (4 preceding siblings ...)
2016-06-26 17:37 ` [PATCH 6/6] powerpc/perf: Export Power9 generic and cache events to sysfs Madhavan Srinivasan
@ 2016-07-05 14:10 ` Michael Ellerman
5 siblings, 0 replies; 9+ messages in thread
From: Michael Ellerman @ 2016-07-05 14:10 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: Madhavan Srinivasan, linuxppc-dev
On Sun, 2016-26-06 at 17:37:04 UTC, Madhavan Srinivasan wrote:
> Factor out some of the power8 pmu macros to
> new a header file to share with power9 pmu code.
> Just code movement and no logic change.
>
> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Series applied to powerpc next, thanks.
https://git.kernel.org/powerpc/c/4d3576b207167bdb7af3140887
cheers
^ permalink raw reply [flat|nested] 9+ messages in thread