path: root/arch/arm/kernel/perf_event.c
diff options
authorMark Rutland <mark.rutland@arm.com>2012-09-12 10:53:23 +0100
committerWill Deacon <will.deacon@arm.com>2014-10-30 12:16:59 +0000
commit67b4305aab0fa993d91fa4c6ea2169cfb3f41c93 (patch)
tree7151ed438a743de534dcd1c20860d64a14664653 /arch/arm/kernel/perf_event.c
parent548a86cae4858433cab7e101bca2c6856ab55887 (diff)
arm: perf: use IDR types for CPU PMUs
For systems with heterogeneous CPUs (e.g. big.LITTLE systems) the PMUs can be different in each cluster, and not all events can be migrated between clusters. To allow userspace to deal with this, it must be possible to address each PMU independently. This patch changes PMUs to be registered with dynamic (IDR) types, allowing them to be targeted individually. Each PMU's type can be found in ${SYSFS_ROOT}/bus/event_source/devices/${PMU_NAME}/type. From userspace, raw events can be targeted at a specific PMU: $ perf stat -e ${PMU_NAME}/config=V,config1=V1,.../ Doing this does not break existing tools which use existing perf types: when perf core can't find a PMU of matching type (in perf_init_event) it'll iterate over the set of all PMUs. If a compatible PMU exists, it'll be found eventually. If more than one compatible PMU exists, the event will be handled by whichever PMU happens to be earlier in the pmus list (which currently will be the last compatible PMU registered). Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm/kernel/perf_event.c')
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index ae96b986d50..7ffb267fb62 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -77,8 +77,12 @@ armpmu_map_event(struct perf_event *event,
u32 raw_event_mask)
u64 config = event->attr.config;
+ int type = event->attr.type;
- switch (event->attr.type) {
+ if (type == event->pmu->type)
+ return armpmu_map_raw_event(raw_event_mask, config);
+ switch (type) {
return armpmu_map_hw_event(event_map, config);