In Power9, L2/L3 bus events are always available as a "bank" of 4 events. To obtain the counts for any of the l2/l3 bus events in a given bank, the user will have to program PMC4 with corresponding l2/l3 bus event for that bank. Patch add a mask and a new pass to updates the mask for each PMU used by L2/L3 bus events and checks the mask to enforce it.
Signed-off-by: Madhavan Srinivasan <ma...@linux.vnet.ibm.com> --- Changelog v1: Removed the callback and added a new pass arch/powerpc/perf/isa207-common.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index 50e598cf644b..ce12e93dbd16 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -219,7 +219,7 @@ int isa207_compute_mmcr(u64 event[], int n_ev, struct perf_event *pevents[]) { unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val; - unsigned int pmc, pmc_inuse; + unsigned int pmc, pmc_inuse, mask=0; int i; pmc_inuse = 0; @@ -312,6 +312,24 @@ int isa207_compute_mmcr(u64 event[], int n_ev, hwc[i] = pmc - 1; } +/* + * Pass 3: to Check for l2/l3 bus event rule. PMC4 + * must be programmed to use L2/L3 bus events in any other PMC[1/2/3]s + */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + 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; + if (unit >= 6 && unit <= 9) + mask |= 1 << (pmc - 1); + } + + if ((mask) && ((mask & 0xf) < 0x8)) { + printk(KERN_ERR "Missing PMC4 L2/L3 Bus event\n"); + return -1; + } + } + /* Return MMCRx values */ mmcr[0] = 0; -- 2.7.4