On hybrid platform, user may want to enable the hardware event only on one PMU. So following syntax is supported:
cpu_core/<hardware event>/ cpu_atom/<hardware event>/ # perf stat -e cpu_core/cpu-cycles/ -a -- sleep 1 Performance counter stats for 'system wide': 6,049,336 cpu_core/cpu-cycles/ 1.003577042 seconds time elapsed It enables the event 'cpu-cycles' only on cpu_core pmu. But for 'cycles' and 'branches', the syntax doesn't work. Before: # perf stat -e cpu_core/cycles/ -a -- sleep 1 event syntax error: 'cpu_core/cycles/' \___ unknown term 'cycles' for pmu 'cpu_core' # perf stat -e cpu_core/branches/ -a -- sleep 1 event syntax error: 'cpu_core/branches/' \___ unknown term 'branches' for pmu 'cpu_core' For 'cpu-cycles', why it works is because the event is defined in /sys/devices/cpu_core/events/. It's added as alias by pmu_add_sys_aliases and it's treated as 'event' when parsing the term->config. We use a similar idea, create a pme_hybrid_fixup table for 'cycles' and 'branches' and add them as aliases. After: # perf stat -e cpu_core/cycles/ -a -- sleep 1 Performance counter stats for 'system wide': 5,769,631 cpu_core/cycles/ 1.003833235 seconds time elapsed # perf stat -e cpu_core/branches/ -a -- sleep 1 Performance counter stats for 'system wide': 490,951 cpu_core/branches/ 1.003693946 seconds time elapsed Signed-off-by: Jin Yao <yao....@linux.intel.com> --- v3: - New patch in v3. tools/perf/util/pmu.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index beff29981101..72e5ae5e868e 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -916,6 +916,35 @@ static int pmu_max_precise(const char *name) return max_precise; } +static void perf_pmu__add_hybrid_aliases(struct list_head *head) +{ + static struct pmu_event pme_hybrid_fixup[] = { + { + .name = "cycles", + .event = "event=0x3c", + }, + { + .name = "branches", + .event = "event=0xc4", + }, + { + .name = 0, + .event = 0, + }, + }; + int i = 0; + + while (1) { + struct pmu_event *pe = &pme_hybrid_fixup[i++]; + + if (!pe->name) + break; + + __perf_pmu__new_alias(head, NULL, (char *)pe->name, NULL, + (char *)pe->event, NULL); + } +} + static struct perf_pmu *pmu_lookup(const char *name) { struct perf_pmu *pmu; @@ -955,6 +984,9 @@ static struct perf_pmu *pmu_lookup(const char *name) pmu_add_cpu_aliases(&aliases, pmu); pmu_add_sys_aliases(&aliases, pmu); + if (pmu->is_hybrid) + perf_pmu__add_hybrid_aliases(&aliases); + INIT_LIST_HEAD(&pmu->format); INIT_LIST_HEAD(&pmu->aliases); INIT_LIST_HEAD(&pmu->caps); -- 2.17.1