arm: perf: cleanups and initial refactoring
Subsystems (3)
Mark Rutland
maintainercover arm: perf: cleanups and initial refactoring
While reorganising the ARM perf backend to provide support for heterogeneous PMUs in big.LITTLE systems, I encountered a couple of issues requiring some preparatory work in addition to some opportunities for general cleanup in the backend. This series consists of those initial cleanups.
Currently the event mapping code in the ARM perf backend requires multi-dimensional tables to map from common event encodings to raw hardware values, where empty slots must be initialised to non-zero values. The current way of organising this results in very large support files which we can simplify with some macro use to remove a few hundred lines and make things more legible.
The PMU naming is somewhat of a mess, with most names not being supported by the perf tool. Given that no-one has complained, it seems that the PMUs are not being accessed by name in a perf context, and we can fix these to be consistent and usable with current tools. We update the OProfile name mangling to ensure that OProfile (which accesses the PMUs in its own namespace) are not adversely affected.
To prepare for reorganisation of the PMU probing code, new platform_device_id values are added to allow ARMv6, ARMv7, and XScale PMU platform_devices to be distinguished.
Thanks,
Mark.
Mark Rutland (8):
arm: perf: move event map macros to pmu.h
arm: perf: add macros for empty event mappings
arm: perf: armv7: condense event maps
arm: perf: armv6: condense event maps
arm: perf: xscale: condense event maps
arm: perf: clean up PMU names
arm: perf: add more specific platform device IDs
arm: perf: krait: stop using singleton PMU
arch/arm/include/asm/perf_event.h | 9 - arch/arm/include/asm/pmu.h | 19 + arch/arm/kernel/perf_event_cpu.c | 13 +- arch/arm/kernel/perf_event_v6.c | 307 +++--------- arch/arm/kernel/perf_event_v7.c | 967 ++++++++---------------------------- arch/arm/kernel/perf_event_xscale.c | 121 +---- arch/arm/oprofile/common.c | 14 +- 7 files changed, 349 insertions(+), 1101 deletions(-)
Signature · 1 line
1.9.1
Mark Rutland
maintainerPATCH 1/8 arm: perf: move event map macros to pmu.h
A few PMU-related macros are now looking a little lonely in asm/perf_event.h now that all other PMU-specific structs, function prototypes and macros live in pmu.h.
So as to make their placement consistent and to make it easier to build atop of the current PMU functionality, let's reunite the entire family in pmu.h
--- arch/arm/include/asm/perf_event.h | 9 --------- arch/arm/include/asm/pmu.h | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-)
arch/arm/include/asm/perf_event.h +0 -9
@@ -12,15 +12,6 @@#ifndef __ARM_PERF_EVENT_H__#define __ARM_PERF_EVENT_H__ -/* -* The ARMv7 CPU PMU supports up to 32 event counters. -*/ -#define ARMPMU_MAX_HWEVENTS 32 - -#define HW_OP_UNSUPPORTED 0xFFFF -#define C (_x) PERF_COUNT_HW_CACHE_##_x -#define CACHE_OP_UNSUPPORTED 0xFFFF -#ifdef CONFIG_HW_PERF_EVENTS struct pt_regs ;extern unsigned long perf_instruction_pointer (struct pt_regs *regs);
arch/arm/include/asm/pmu.h +9 -0
@@ -42,6 +42,15 @@ struct arm_pmu_platdata {#ifdef CONFIG_HW_PERF_EVENTS +/* +* The ARMv7 CPU PMU supports up to 32 event counters. +*/ +#define ARMPMU_MAX_HWEVENTS 32 + +#define HW_OP_UNSUPPORTED 0xFFFF +#define C (_x) PERF_COUNT_HW_CACHE_##_x +#define CACHE_OP_UNSUPPORTED 0xFFFF +/* The events for a given PMU register set. */ struct pmu_hw_events {/*
Signature · 1 line
1.9.1
Mark Rutland
maintainerPATCH 2/8 arm: perf: add macros for empty event mappings
In reply to Mark RutlandWe currently map from userspace-ABI standard event numbers to hardware-specific IDs by use of two arrays, *_perf_map and *_perf_cache_map. While we use designated initializers to initialize the events we care about, zero is typically a valid hardware event number, and thus we have to explicitly initialize unsupported event mappings to a nonzero value ({HW,CACHE}_OP_UNSUPPORTED).
In the case of the *_cache_map, this requires initialising almost every entry in a 3-dimensional array to CACHE_OP_UNSUPPORTED, requiring over a hundred lines to add eleven supported events in the case of Cortex A9.
So as to take up less space and make the tables easier to deal with, this patch adds two new macros to initialize every entry in these tables to the *_UNSUPPORTED values. Supported events can be overridden individually through the use of designated initializers.
--- arch/arm/include/asm/pmu.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm/include/asm/pmu.h +10 -0
@@ -51,6 +51,16 @@ struct arm_pmu_platdata {#define C (_x) PERF_COUNT_HW_CACHE_##_x#define CACHE_OP_UNSUPPORTED 0xFFFF +#define PERF_MAP_ALL_UNSUPPORTED \ + [0 ... PERF_COUNT_HW_MAX - 1] = HW_OP_UNSUPPORTED + +#define PERF_CACHE_MAP_ALL_UNSUPPORTED \ +[0 ... C(MAX) - 1] = { \ + [0 ... C(OP_MAX) - 1] = { \ + [0 ... C(RESULT_MAX) - 1] = CACHE_OP_UNSUPPORTED, \ + }, \ +} +/* The events for a given PMU register set. */ struct pmu_hw_events {/*
Signature · 1 line
1.9.1
Mark Rutland
maintainerPATCH 3/8 arm: perf: armv7: condense event maps
In reply to Mark RutlandNow that we have macros for declaring fully invalid event maps, put them to work for all the ARMv7 PMU event maps. While this necessitates repeating common indices, we no longer need to refer to *_UNSUPPORTED events at all, and it makes it possible for the even maps to fit on a single page on a reasonably sized monitor.
--- arch/arm/kernel/perf_event_v7.c | 949 +++++++++------------------------------- 1 file changed, 206 insertions(+), 743 deletions(-)
arch/arm/kernel/perf_event_v7.c +206 -743
@@ -148,137 +148,62 @@ enum krait_perf_types {* accesses/misses in hardware. */ static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV7_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV7_PERFCTR_INSTR_EXECUTED , [PERF_COUNT_HW_CACHE_REFERENCES ] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , [PERF_COUNT_HW_CACHE_MISSES ] =ARMV7_PERFCTR_L1_DCACHE_REFILL , [PERF_COUNT_HW_BRANCH_INSTRUCTIONS ] =ARMV7_PERFCTR_PC_WRITE , [PERF_COUNT_HW_BRANCH_MISSES ] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - [PERF_COUNT_HW_BUS_CYCLES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND ] =ARMV7_A8_PERFCTR_STALL_ISIDE , - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND ] =HW_OP_UNSUPPORTED , };static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { -/* -* The performance counters don't differentiate between read -* and write accesses/misses so this isn't strictly correct, -* but it's the best we can do. Writes and reads get -* combined. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_A8_PERFCTR_L2_CACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_A8_PERFCTR_L2_CACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_A8_PERFCTR_L2_CACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_A8_PERFCTR_L2_CACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + +/* +* The performance counters don't differentiate between read and write +* accesses/misses so this isn't strictly correct, but it's the best we +* can do. Writes and reads get combined. +*/ + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + + [C (L1I )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS , + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , + + [C (LL )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_A8_PERFCTR_L2_CACHE_ACCESS , + [C (LL )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_A8_PERFCTR_L2_CACHE_REFILL , + [C (LL )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_A8_PERFCTR_L2_CACHE_ACCESS , + [C (LL )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_A8_PERFCTR_L2_CACHE_REFILL , + + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + + [C (BPU )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , };/* * Cortex-A9 HW events mapping */ static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV7_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV7_A9_PERFCTR_INSTR_CORE_RENAME , [PERF_COUNT_HW_CACHE_REFERENCES ] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , [PERF_COUNT_HW_CACHE_MISSES ] =ARMV7_PERFCTR_L1_DCACHE_REFILL , [PERF_COUNT_HW_BRANCH_INSTRUCTIONS ] =ARMV7_PERFCTR_PC_WRITE , [PERF_COUNT_HW_BRANCH_MISSES ] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - [PERF_COUNT_HW_BUS_CYCLES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND ] =ARMV7_A9_PERFCTR_STALL_ICACHE , [PERF_COUNT_HW_STALLED_CYCLES_BACKEND ] =ARMV7_A9_PERFCTR_STALL_DISPATCH , };
@@ -286,238 +211,83 @@ static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { -/* -* The performance counters don't differentiate between read -* and write accesses/misses so this isn't strictly correct, -* but it's the best we can do. Writes and reads get -* combined. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + +/* +* The performance counters don't differentiate between read and write +* accesses/misses so this isn't strictly correct, but it's the best we +* can do. Writes and reads get combined. +*/ + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , + + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + + [C (BPU )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , };/* * Cortex-A5 HW events mapping */ static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV7_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV7_PERFCTR_INSTR_EXECUTED , [PERF_COUNT_HW_CACHE_REFERENCES ] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , [PERF_COUNT_HW_CACHE_MISSES ] =ARMV7_PERFCTR_L1_DCACHE_REFILL , [PERF_COUNT_HW_BRANCH_INSTRUCTIONS ] =ARMV7_PERFCTR_PC_WRITE , [PERF_COUNT_HW_BRANCH_MISSES ] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - [PERF_COUNT_HW_BUS_CYCLES ] =HW_OP_UNSUPPORTED , - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND ] =HW_OP_UNSUPPORTED , - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND ] =HW_OP_UNSUPPORTED , };static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =ARMV7_A5_PERFCTR_PREFETCH_LINEFILL , - [C (RESULT_MISS )] =ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP , - }, - }, - [C (L1I )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_ICACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, -/* -* The prefetch counters don't differentiate between the I -* side and the D side. -*/ - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =ARMV7_A5_PERFCTR_PREFETCH_LINEFILL , - [C (RESULT_MISS )] =ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + [C (L1D )][C (OP_PREFETCH )][C (RESULT_ACCESS )] =ARMV7_A5_PERFCTR_PREFETCH_LINEFILL , + [C (L1D )][C (OP_PREFETCH )][C (RESULT_MISS )] =ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP , + + [C (L1I )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_ICACHE_ACCESS , + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , +/* +* The prefetch counters don't differentiate between the I side and the +* D side. +*/ + [C (L1I )][C (OP_PREFETCH )][C (RESULT_ACCESS )] =ARMV7_A5_PERFCTR_PREFETCH_LINEFILL , + [C (L1I )][C (OP_PREFETCH )][C (RESULT_MISS )] =ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP , + + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + + [C (BPU )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , };/* * Cortex-A15 HW events mapping */ static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV7_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV7_PERFCTR_INSTR_EXECUTED , [PERF_COUNT_HW_CACHE_REFERENCES ] =ARMV7_PERFCTR_L1_DCACHE_ACCESS ,
@@ -525,123 +295,48 @@ static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC, [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, };static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ , - [C (RESULT_MISS )] =ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE , - [C (RESULT_MISS )] =ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { -/* -* Not all performance counters differentiate between read -* and write accesses/misses so we're not always strictly -* correct, but it's the best we can do. Writes and reads get -* combined in these cases. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_ICACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ , - [C (RESULT_MISS )] =ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE , - [C (RESULT_MISS )] =ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE , + +/* +* Not all performance counters differentiate between read and write +* accesses/misses so we're not always strictly correct, but it's the +* best we can do. Writes and reads get combined in these cases. +*/ + [C (L1I )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_ICACHE_ACCESS , + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , + + [C (LL )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ , + [C (LL )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ , + [C (LL )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE , + [C (LL )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE , + + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + + [C (BPU )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , };/* * Cortex-A7 HW events mapping */ static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV7_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV7_PERFCTR_INSTR_EXECUTED , [PERF_COUNT_HW_CACHE_REFERENCES ] =ARMV7_PERFCTR_L1_DCACHE_ACCESS ,
@@ -649,123 +344,48 @@ static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, };static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { -/* -* The performance counters don't differentiate between read -* and write accesses/misses so this isn't strictly correct, -* but it's the best we can do. Writes and reads get -* combined. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_ICACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L2_CACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L2_CACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L2_CACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L2_CACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + +/* +* The performance counters don't differentiate between read and write +* accesses/misses so this isn't strictly correct, but it's the best we +* can do. Writes and reads get combined. +*/ + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + + [C (L1I )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_ICACHE_ACCESS , + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , + + [C (LL )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L2_CACHE_ACCESS , + [C (LL )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L2_CACHE_REFILL , + [C (LL )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L2_CACHE_ACCESS , + [C (LL )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_L2_CACHE_REFILL , + + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + + [C (BPU )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , };/* * Cortex-A12 HW events mapping */ static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV7_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV7_PERFCTR_INSTR_EXECUTED , [PERF_COUNT_HW_CACHE_REFERENCES ] =ARMV7_PERFCTR_L1_DCACHE_ACCESS ,
@@ -773,138 +393,60 @@ static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC, [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, };static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { -/* -* Not all performance counters differentiate between read -* and write accesses/misses so we're not always strictly -* correct, but it's the best we can do. Writes and reads get -* combined in these cases. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_ICACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L2_CACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L2_CACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_A12_PERFCTR_PF_TLB_REFILL , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + +/* +* Not all performance counters differentiate between read and write +* accesses/misses so we're not always strictly correct, but it's the +* best we can do. Writes and reads get combined in these cases. +*/ + [C (L1I )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_ICACHE_ACCESS , + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_ICACHE_REFILL , + + [C (LL )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ , + [C (LL )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L2_CACHE_REFILL , + [C (LL )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE , + [C (LL )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_L2_CACHE_REFILL , + + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_DTLB_REFILL , + [C (DTLB )][C (OP_PREFETCH )][C (RESULT_MISS )] =ARMV7_A12_PERFCTR_PF_TLB_REFILL , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_ITLB_REFILL , + + [C (BPU )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , };/* * Krait HW events mapping */ static const unsigned krait_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV7_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV7_PERFCTR_INSTR_EXECUTED , - [PERF_COUNT_HW_CACHE_REFERENCES ] =HW_OP_UNSUPPORTED , - [PERF_COUNT_HW_CACHE_MISSES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_BRANCH_INSTRUCTIONS ] =ARMV7_PERFCTR_PC_WRITE , [PERF_COUNT_HW_BRANCH_MISSES ] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , [PERF_COUNT_HW_BUS_CYCLES ] =ARMV7_PERFCTR_CLOCK_CYCLES , };static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV7_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV7_PERFCTR_INSTR_EXECUTED , - [PERF_COUNT_HW_CACHE_REFERENCES ] =HW_OP_UNSUPPORTED , - [PERF_COUNT_HW_CACHE_MISSES ] =HW_OP_UNSUPPORTED , - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_BRANCH_MISSES ] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , [PERF_COUNT_HW_BUS_CYCLES ] =ARMV7_PERFCTR_CLOCK_CYCLES , };
@@ -912,110 +454,31 @@ static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { -/* -* The performance counters don't differentiate between read -* and write accesses/misses so this isn't strictly correct, -* but it's the best we can do. Writes and reads get -* combined. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_ICACHE_ACCESS , - [C (RESULT_MISS )] =KRAIT_PERFCTR_L1_ICACHE_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_DTLB_ACCESS , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_DTLB_ACCESS , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_ITLB_ACCESS , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_ITLB_ACCESS , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , - [C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + +/* +* The performance counters don't differentiate between read and write +* accesses/misses so this isn't strictly correct, but it's the best we +* can do. Writes and reads get combined. +*/ + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_L1_DCACHE_ACCESS , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_L1_DCACHE_REFILL , + + [C (L1I )][C (OP_READ )][C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_ICACHE_ACCESS , + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =KRAIT_PERFCTR_L1_ICACHE_MISS , + + [C (DTLB )][C (OP_READ )][C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_DTLB_ACCESS , + [C (DTLB )][C (OP_WRITE )][C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_DTLB_ACCESS , + + [C (ITLB )][C (OP_READ )][C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_ITLB_ACCESS , + [C (ITLB )][C (OP_WRITE )][C (RESULT_ACCESS )] =KRAIT_PERFCTR_L1_ITLB_ACCESS , + + [C (BPU )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_READ )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV7_PERFCTR_PC_BRANCH_PRED , + [C (BPU )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV7_PERFCTR_PC_BRANCH_MIS_PRED , };/*
Signature · 1 line
1.9.1
Mark Rutland
maintainerPATCH 4/8 arm: perf: armv6: condense event maps
In reply to Mark RutlandNow that we have macros for declaring fully invalid event maps, put them to work for all the ARMv6 PMU event maps. While this necessitates repeating common indices, we no longer need to refer to *_UNSUPPORTED events at all, and it makes it possible for the even maps to fit on a single page on a reasonably sized monitor.
--- arch/arm/kernel/perf_event_v6.c | 271 +++++++--------------------------------- 1 file changed, 47 insertions(+), 224 deletions(-)
arch/arm/kernel/perf_event_v6.c +47 -224
@@ -65,13 +65,11 @@ enum armv6_counters {* accesses/misses in hardware. */ static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV6_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV6_PERFCTR_INSTR_EXEC , - [PERF_COUNT_HW_CACHE_REFERENCES ] =HW_OP_UNSUPPORTED , - [PERF_COUNT_HW_CACHE_MISSES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_BRANCH_INSTRUCTIONS ] =ARMV6_PERFCTR_BR_EXEC , [PERF_COUNT_HW_BRANCH_MISSES ] =ARMV6_PERFCTR_BR_MISPREDICT , - [PERF_COUNT_HW_BUS_CYCLES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND ] =ARMV6_PERFCTR_IBUF_STALL , [PERF_COUNT_HW_STALLED_CYCLES_BACKEND ] =ARMV6_PERFCTR_LSU_FULL_STALL , };
@@ -79,116 +77,31 @@ static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { -/* -* The performance counters don't differentiate between read -* and write accesses/misses so this isn't strictly correct, -* but it's the best we can do. Writes and reads get -* combined. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =ARMV6_PERFCTR_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV6_PERFCTR_DCACHE_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =ARMV6_PERFCTR_DCACHE_ACCESS , - [C (RESULT_MISS )] =ARMV6_PERFCTR_DCACHE_MISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6_PERFCTR_ICACHE_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { -/* -* The ARM performance counters can count micro DTLB misses, -* micro ITLB misses and main TLB misses. There isn't an event -* for TLB misses, so use the micro misses here and if users -* want the main TLB misses they can use a raw counter. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6_PERFCTR_DTLB_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6_PERFCTR_DTLB_MISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6_PERFCTR_ITLB_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6_PERFCTR_ITLB_MISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + +/* +* The performance counters don't differentiate between read and write +* accesses/misses so this isn't strictly correct, but it's the best we +* can do. Writes and reads get combined. +*/ + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV6_PERFCTR_DCACHE_ACCESS , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV6_PERFCTR_DCACHE_MISS , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV6_PERFCTR_DCACHE_ACCESS , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV6_PERFCTR_DCACHE_MISS , + + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =ARMV6_PERFCTR_ICACHE_MISS , + +/* +* The ARM performance counters can count micro DTLB misses, micro ITLB +* misses and main TLB misses. There isn't an event for TLB misses, so +* use the micro misses here and if users want the main TLB misses they +* can use a raw counter. +*/ + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV6_PERFCTR_DTLB_MISS , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV6_PERFCTR_DTLB_MISS , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV6_PERFCTR_ITLB_MISS , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV6_PERFCTR_ITLB_MISS , };enum armv6mpcore_perf_types {
@@ -220,13 +133,11 @@ enum armv6mpcore_perf_types {* accesses/misses in hardware. */ static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =ARMV6MPCORE_PERFCTR_CPU_CYCLES , [PERF_COUNT_HW_INSTRUCTIONS ] =ARMV6MPCORE_PERFCTR_INSTR_EXEC , - [PERF_COUNT_HW_CACHE_REFERENCES ] =HW_OP_UNSUPPORTED , - [PERF_COUNT_HW_CACHE_MISSES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_BRANCH_INSTRUCTIONS ] =ARMV6MPCORE_PERFCTR_BR_EXEC , [PERF_COUNT_HW_BRANCH_MISSES ] =ARMV6MPCORE_PERFCTR_BR_MISPREDICT , - [PERF_COUNT_HW_BUS_CYCLES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND ] =ARMV6MPCORE_PERFCTR_IBUF_STALL , [PERF_COUNT_HW_STALLED_CYCLES_BACKEND ] =ARMV6MPCORE_PERFCTR_LSU_FULL_STALL , };
@@ -234,114 +145,26 @@ static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] = -ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS , - [C (RESULT_MISS )] = -ARMV6MPCORE_PERFCTR_DCACHE_RDMISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] = -ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS , - [C (RESULT_MISS )] = -ARMV6MPCORE_PERFCTR_DCACHE_WRMISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_ICACHE_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { -/* -* The ARM performance counters can count micro DTLB misses, -* micro ITLB misses and main TLB misses. There isn't an event -* for TLB misses, so use the micro misses here and if users -* want the main TLB misses they can use a raw counter. -*/ - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_DTLB_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_DTLB_MISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_ITLB_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_ITLB_MISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_DCACHE_RDMISS , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_DCACHE_WRMISS , + + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_ICACHE_MISS , + +/* +* The ARM performance counters can count micro DTLB misses, micro ITLB +* misses and main TLB misses. There isn't an event for TLB misses, so +* use the micro misses here and if users want the main TLB misses they +* can use a raw counter. +*/ + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_DTLB_MISS , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_DTLB_MISS , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_ITLB_MISS , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =ARMV6MPCORE_PERFCTR_ITLB_MISS , }; static inline unsigned long
Signature · 1 line
1.9.1
Mark Rutland
maintainerPATCH 5/8 arm: perf: xscale: condense event maps
In reply to Mark RutlandNow that we have macros for declaring fully invalid event maps, put them to work for the XScale PMU event maps. While this necessitates repeating common indices, we no longer need to refer to *_UNSUPPORTED events at all, and it makes it possible for the even maps to fit on a single page on a reasonably sized monitor.
--- arch/arm/kernel/perf_event_xscale.c | 117 +++++------------------------------- 1 file changed, 15 insertions(+), 102 deletions(-)
arch/arm/kernel/perf_event_xscale.c +15 -102
@@ -48,118 +48,31 @@ enum xscale_counters { };static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX ] = { +PERF_MAP_ALL_UNSUPPORTED , [PERF_COUNT_HW_CPU_CYCLES ] =XSCALE_PERFCTR_CCNT , [PERF_COUNT_HW_INSTRUCTIONS ] =XSCALE_PERFCTR_INSTRUCTION , - [PERF_COUNT_HW_CACHE_REFERENCES ] =HW_OP_UNSUPPORTED , - [PERF_COUNT_HW_CACHE_MISSES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_BRANCH_INSTRUCTIONS ] =XSCALE_PERFCTR_BRANCH , [PERF_COUNT_HW_BRANCH_MISSES ] =XSCALE_PERFCTR_BRANCH_MISS , - [PERF_COUNT_HW_BUS_CYCLES ] =HW_OP_UNSUPPORTED , [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND ] =XSCALE_PERFCTR_ICACHE_NO_DELIVER , - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND ] =HW_OP_UNSUPPORTED , };static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ] [PERF_COUNT_HW_CACHE_RESULT_MAX ] = { - [C (L1D )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =XSCALE_PERFCTR_DCACHE_ACCESS , - [C (RESULT_MISS )] =XSCALE_PERFCTR_DCACHE_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =XSCALE_PERFCTR_DCACHE_ACCESS , - [C (RESULT_MISS )] =XSCALE_PERFCTR_DCACHE_MISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (L1I )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =XSCALE_PERFCTR_ICACHE_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (LL )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (DTLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =XSCALE_PERFCTR_DTLB_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =XSCALE_PERFCTR_DTLB_MISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (ITLB )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =XSCALE_PERFCTR_ITLB_MISS , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =XSCALE_PERFCTR_ITLB_MISS , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (BPU )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, - [C (NODE )] = { - [C (OP_READ )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_WRITE )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - [C (OP_PREFETCH )] = { - [C (RESULT_ACCESS )] =CACHE_OP_UNSUPPORTED , - [C (RESULT_MISS )] =CACHE_OP_UNSUPPORTED , - }, - }, +PERF_CACHE_MAP_ALL_UNSUPPORTED , + + [C (L1D )][C (OP_READ )][C (RESULT_ACCESS )] =XSCALE_PERFCTR_DCACHE_ACCESS , + [C (L1D )][C (OP_READ )][C (RESULT_MISS )] =XSCALE_PERFCTR_DCACHE_MISS , + [C (L1D )][C (OP_WRITE )][C (RESULT_ACCESS )] =XSCALE_PERFCTR_DCACHE_ACCESS , + [C (L1D )][C (OP_WRITE )][C (RESULT_MISS )] =XSCALE_PERFCTR_DCACHE_MISS , + + [C (L1I )][C (OP_READ )][C (RESULT_MISS )] =XSCALE_PERFCTR_ICACHE_MISS , + + [C (DTLB )][C (OP_READ )][C (RESULT_MISS )] =XSCALE_PERFCTR_DTLB_MISS , + [C (DTLB )][C (OP_WRITE )][C (RESULT_MISS )] =XSCALE_PERFCTR_DTLB_MISS , + + [C (ITLB )][C (OP_READ )][C (RESULT_MISS )] =XSCALE_PERFCTR_ITLB_MISS , + [C (ITLB )][C (OP_WRITE )][C (RESULT_MISS )] =XSCALE_PERFCTR_ITLB_MISS , };#define XSCALE_PMU_ENABLE 0x001
Signature · 1 line
1.9.1
Mark Rutland
maintainerPATCH 6/8 arm: perf: clean up PMU names
In reply to Mark RutlandThe perf userspace tools can't handle dashes or spaces in PMU names, which conflicts with the current naming scheme in the arm perf backend. This prevents these PMUs from being accessed by name from the perf tools. Additionally the ARMv6 pmus are named "v6", which does not fully distinguish them in the sys/bus/event_source namespace.
This patch renames the PMUs consistently to a lower case form with underscores, e.g. "armv6_1176", "armv7_cortex_a9". This is both readily accepted by today's perf tool, and far easier to type than the (apparently unused) convention in use previously. The OProfile name conversion code is updated to handle this.
Due to a copy-paste error involving two "xscale1" entries, "xscale2" has never been matched by the name OProfile name mapping. While we're updating names, this is corrected.
--- arch/arm/kernel/perf_event_cpu.c | 10 +++++++--- arch/arm/kernel/perf_event_v6.c | 36 ++++++++++++++++++++++++++++++++---- arch/arm/kernel/perf_event_v7.c | 16 ++++++++-------- arch/arm/kernel/perf_event_xscale.c | 4 ++-- arch/arm/oprofile/common.c | 14 ++++++++------ 5 files changed, 57 insertions(+), 23 deletions(-)
arch/arm/kernel/perf_event_cpu.c +7 -3
@@ -233,8 +233,8 @@ static struct of_device_id cpu_pmu_of_device_ids[] = { {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init}, {.compatible = "arm,cortex-a5-pmu", .data = armv7_a5_pmu_init}, {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init}, - {.compatible = "arm,arm1176-pmu", .data = armv6pmu_init}, - {.compatible = "arm,arm1136-pmu", .data = armv6pmu_init}, + {.compatible = "arm,arm1176-pmu", .data = armv6_1176_pmu_init}, + {.compatible = "arm,arm1136-pmu", .data = armv6_1136_pmu_init}, {.compatible = "qcom,krait-pmu", .data = krait_pmu_init}, {}, };
@@ -260,9 +260,13 @@ static int probe_current_pmu(struct arm_pmu *pmu)if (implementor ==ARM_CPU_IMP_ARM ) {switch (part_number) {case ARM_CPU_PART_ARM1136 : + ret =armv6_1136_pmu_init (pmu); +break ;case ARM_CPU_PART_ARM1156 : + ret =armv6_1156_pmu_init (pmu); +break ;case ARM_CPU_PART_ARM1176 : - ret =armv6pmu_init (pmu); + ret =armv6_1176_pmu_init (pmu);break ;case ARM_CPU_PART_ARM11MPCORE : ret =armv6mpcore_pmu_init (pmu);
arch/arm/kernel/perf_event_v6.c +32 -4
@@ -476,9 +476,8 @@ static int armv6_map_event(struct perf_event *event) &armv6_perf_cache_map, 0xFF); } -static int armv6pmu_init (struct arm_pmu *cpu_pmu) +static void armv6pmu_init (struct arm_pmu *cpu_pmu) { - cpu_pmu->name ="v6" ; cpu_pmu->handle_irq = armv6pmu_handle_irq; cpu_pmu->enable = armv6pmu_enable_event; cpu_pmu->disable = armv6pmu_disable_event;
@@ -490,7 +489,26 @@ static int armv6pmu_init(struct arm_pmu *cpu_pmu) cpu_pmu->map_event = armv6_map_event; cpu_pmu->num_events =3 ; cpu_pmu->max_period = (1LLU <<32 ) -1 ; +} + +static int armv6_1136_pmu_init (struct arm_pmu *cpu_pmu) +{ +armv6pmu_init (cpu_pmu); + cpu_pmu->name ="armv6_1136" + return 0; +} + +static int armv6_1156_pmu_init (struct arm_pmu *cpu_pmu) +{ +armv6pmu_init (cpu_pmu); + cpu_pmu->name ="armv6_1156" + return 0; +} +static int armv6_1176_pmu_init (struct arm_pmu *cpu_pmu) +{ +armv6pmu_init (cpu_pmu); + cpu_pmu->name ="armv6_1176" return 0; }
@@ -510,7 +528,7 @@ static int armv6mpcore_map_event(struct perf_event *event)static int armv6mpcore_pmu_init (struct arm_pmu *cpu_pmu) { - cpu_pmu->name ="v6mpcore" ; + cpu_pmu->name ="armv6_11mpcore" ; cpu_pmu->handle_irq = armv6pmu_handle_irq; cpu_pmu->enable = armv6pmu_enable_event; cpu_pmu->disable = armv6mpcore_pmu_disable_event;
@@ -526,7 +544,17 @@ static int armv6mpcore_pmu_init(struct arm_pmu *cpu_pmu) return 0; }#else -static int armv6pmu_init (struct arm_pmu *cpu_pmu) +static int armv6_1136_pmu_init (struct arm_pmu *cpu_pmu) +{ +return -ENODEV ; +} + +static int armv6_1156_pmu_init (struct arm_pmu *cpu_pmu) +{ +return -ENODEV ; +} + +static int armv6_1176_pmu_init (struct arm_pmu *cpu_pmu) {return -ENODEV ; }
arch/arm/kernel/perf_event_v7.c +8 -8
@@ -1008,7 +1008,7 @@ static u32 armv7_read_num_pmnc_events(void)static int armv7_a8_pmu_init (struct arm_pmu *cpu_pmu) {armv7pmu_init (cpu_pmu); - cpu_pmu->name ="ARMv7 Cortex-A8" ; + cpu_pmu->name ="armv7_cortex_a8" ; cpu_pmu->map_event = armv7_a8_map_event; cpu_pmu->num_events =armv7_read_num_pmnc_events ();return 0 ;
@@ -1017,7 +1017,7 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)static int armv7_a9_pmu_init (struct arm_pmu *cpu_pmu) {armv7pmu_init (cpu_pmu); - cpu_pmu->name ="ARMv7 Cortex-A9" ; + cpu_pmu->name ="armv7_cortex_a9" ; cpu_pmu->map_event = armv7_a9_map_event; cpu_pmu->num_events =armv7_read_num_pmnc_events ();return 0 ;
@@ -1026,7 +1026,7 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)static int armv7_a5_pmu_init (struct arm_pmu *cpu_pmu) {armv7pmu_init (cpu_pmu); - cpu_pmu->name ="ARMv7 Cortex-A5" ; + cpu_pmu->name ="armv7_cortex_a5" ; cpu_pmu->map_event = armv7_a5_map_event; cpu_pmu->num_events =armv7_read_num_pmnc_events ();return 0 ;
@@ -1035,7 +1035,7 @@ static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)static int armv7_a15_pmu_init (struct arm_pmu *cpu_pmu) {armv7pmu_init (cpu_pmu); - cpu_pmu->name ="ARMv7 Cortex-A15" ; + cpu_pmu->name ="armv7_cortex_a15" ; cpu_pmu->map_event = armv7_a15_map_event; cpu_pmu->num_events =armv7_read_num_pmnc_events (); cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
@@ -1045,7 +1045,7 @@ static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)static int armv7_a7_pmu_init (struct arm_pmu *cpu_pmu) {armv7pmu_init (cpu_pmu); - cpu_pmu->name ="ARMv7 Cortex-A7" ; + cpu_pmu->name ="armv7_cortex_a7" ; cpu_pmu->map_event = armv7_a7_map_event; cpu_pmu->num_events =armv7_read_num_pmnc_events (); cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
@@ -1055,7 +1055,7 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)static int armv7_a12_pmu_init (struct arm_pmu *cpu_pmu) {armv7pmu_init (cpu_pmu); - cpu_pmu->name ="ARMv7 Cortex-A12" ; + cpu_pmu->name ="armv7_cortex_a12" ; cpu_pmu->map_event = armv7_a12_map_event; cpu_pmu->num_events =armv7_read_num_pmnc_events (); cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
@@ -1065,7 +1065,7 @@ static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)static int armv7_a17_pmu_init (struct arm_pmu *cpu_pmu) {armv7_a12_pmu_init (cpu_pmu); - cpu_pmu->name ="ARMv7 Cortex-A17" ; + cpu_pmu->name ="armv7_cortex_a17" ;return 0 ; }
@@ -1444,7 +1444,7 @@ static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,static int krait_pmu_init (struct arm_pmu *cpu_pmu) {armv7pmu_init (cpu_pmu); - cpu_pmu->name ="ARMv7 Krait" ; + cpu_pmu->name ="armv7_krait" ;/* Some early versions of Krait don't support PC write events */ if (of_property_read_bool (cpu_pmu->plat_device->dev.of_node,"qcom,no-pc-write" ))
arch/arm/kernel/perf_event_xscale.c +2 -2
@@ -355,7 +355,7 @@ static int xscale_map_event(struct perf_event *event)static int xscale1pmu_init (struct arm_pmu *cpu_pmu) { - cpu_pmu->name ="xscale1" ; + cpu_pmu->name ="armv5_xscale1" ; cpu_pmu->handle_irq = xscale1pmu_handle_irq; cpu_pmu->enable = xscale1pmu_enable_event; cpu_pmu->disable = xscale1pmu_disable_event;
@@ -725,7 +725,7 @@ static inline void xscale2pmu_write_counter(struct perf_event *event, u32 val)static int xscale2pmu_init (struct arm_pmu *cpu_pmu) { - cpu_pmu->name ="xscale2" ; + cpu_pmu->name ="armv5_xscale2" ; cpu_pmu->handle_irq = xscale2pmu_handle_irq; cpu_pmu->enable = xscale2pmu_enable_event; cpu_pmu->disable = xscale2pmu_disable_event;
arch/arm/oprofile/common.c +8 -6
@@ -33,12 +33,14 @@ static struct op_perf_name {char *perf_name;char *op_name; } op_perf_name_map[] = { - { "xscale1", "arm/xscale1" }, - { "xscale1", "arm/xscale2" }, - { "v6", "arm/armv6" }, - { "v6mpcore", "arm/mpcore" }, - { "ARMv7 Cortex-A8", "arm/armv7" }, - { "ARMv7 Cortex-A9", "arm/armv7-ca9" }, + { "armv5_xscale1", "arm/xscale1" }, + { "armv5_xscale2", "arm/xscale2" }, + { "armv6_1136", "arm/armv6" }, + { "armv6_1156", "arm/armv6" }, + { "armv6_1176", "arm/armv6" }, + { "armv6_11mpcore", "arm/mpcore" }, + { "armv7_cortex_a8", "arm/armv7" }, + { "armv7_cortex_a9", "arm/armv7-ca9" }, }; char *op_name_from_perf_id(void)
Signature · 1 line
1.9.1
Mark Rutland
maintainerPATCH 7/8 arm: perf: add more specific platform device IDs
In reply to Mark RutlandWhen described in DT, PMUs are given very specific compatible strings (e.g. "arm,cortex-a15-pmu") which makes it very easy to reorganise the way individual PMUs are handled (i.e. we can easily split them into separate drivers). The same is not true of PMUs described in board files, which are all use the platform_device_id "arm-pmu" and must all be handled by the same driver.
To enable splitting the ARMv6, ARMv7, and XScale PMU drivers we need board files to identify which variant they provide. As a first step, this patch adds new platform_device_id values: "armv6-pmu", "armv7-pmu, and "xscale-pmu".
Once board files are moved over and all existing uses of "arm-pmu" are gone, we can split the existing driver apart.
--- arch/arm/kernel/perf_event_cpu.c | 3 +++ 1 file changed, 3 insertions(+)
arch/arm/kernel/perf_event_cpu.c +3 -0
@@ -241,6 +241,9 @@ static struct of_device_id cpu_pmu_of_device_ids[] = {static struct platform_device_id cpu_pmu_plat_device_ids[] = { {.name ="arm-pmu" }, + {.name ="armv6-pmu" }, + {.name ="armv7-pmu" }, + {.name ="xscale-pmu" }, {}, };
Signature · 1 line
1.9.1
PATCH 7/8 arm: perf: add more specific platform device IDs
Quoted 26 lines · Mark Rutland
When described in DT, PMUs are given very specific compatible strings (e.g. "arm,cortex-a15-pmu") which makes it very easy to reorganise the way individual PMUs are handled (i.e. we can easily split them into separate drivers). The same is not true of PMUs described in board files, which are all use the
platform_device_id"arm-pmu" and must all be handled by the same driver.To enable splitting the ARMv6, ARMv7, and XScale PMU drivers we need board files to identify which variant they provide. As a first step, this patch adds new
platform_device_idvalues: "armv6-pmu", "armv7-pmu, and "xscale-pmu".Once board files are moved over and all existing uses of "arm-pmu" are gone, we can split the existing driver apart.
Signed-off-by Mark Rutland <[email protected]>Cc Will Deacon <[email protected]>--- arch/arm/kernel/perf_event_cpu.c | 3 +++ 1 file changed, 3 insertions(+)arch/arm/kernel/perf_event_cpu.c +0
-0
arch/arm/kernel/perf_event_cpu.c static struct of_device_id cpu_pmu_of_device_ids[] = { · line 246
Quoted 6 lines
arch/arm/kernel/perf_event_cpu.c +3
-0@@ -241,6 +241,9 @@ static struct of_device_id cpu_pmu_of_device_ids[] = {static struct platform_device_id cpu_pmu_plat_device_ids[] = { {.name ="arm-pmu" }, + {.name ="armv6-pmu" }, + {.name ="armv7-pmu" }, + {.name ="xscale-pmu" },
Will
Mark Rutland
maintainerPATCH 8/8 arm: perf: krait: stop using singleton PMU
In reply to Mark RutlandCurrently the krait_pmu_{enable,disable}_event functions use the global cpu_pmu variable while all the other pmu enable/disable functions derive this from the event argument.
This patch brings the Krait functions into line with the rest of the PMU backends by deriving the address of the pmu from the event argument.
--- arch/arm/kernel/perf_event_v7.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/kernel/perf_event_v7.c +2 -0
@@ -1286,6 +1286,7 @@ static void krait_pmu_disable_event(struct perf_event *event)unsigned long flags;struct hw_perf_event *hwc = &event->hw;int idx = hwc->idx; +struct arm_pmu *cpu_pmu =to_arm_pmu (event->pmu);struct pmu_hw_events *events = cpu_pmu->get_hw_events ();/* Disable counter and interrupt */
@@ -1311,6 +1312,7 @@ static void krait_pmu_enable_event(struct perf_event *event)unsigned long flags;struct hw_perf_event *hwc = &event->hw;int idx = hwc->idx; +struct arm_pmu *cpu_pmu =to_arm_pmu (event->pmu);struct pmu_hw_events *events = cpu_pmu->get_hw_events ();/*
Signature · 1 line
1.9.1
PATCH 8/8 arm: perf: krait: stop using singleton PMU
Quoted 9 lines · Mark Rutland
Currently the krait_pmu_{enable,disable}_event functions use the global
cpu_pmuvariable while all the other pmu enable/disable functions derive this from the event argument.This patch brings the Krait functions into line with the rest of the PMU backends by deriving the address of the pmu from the event argument.
Signed-off-by Mark Rutland <[email protected]>Cc Will Deacon <[email protected]>
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 8/8 arm: perf: krait: stop using singleton PMU
In reply to Mark RutlandQuoted 10 lines · Mark Rutland
Currently the krait_pmu_{enable,disable}_event functions use the global
cpu_pmuvariable while all the other pmu enable/disable functions derive this from the event argument.This patch brings the Krait functions into line with the rest of the PMU backends by deriving the address of the pmu from the event argument.
Signed-off-by Mark Rutland <[email protected]>Cc Will Deacon <[email protected]>Cc Stephen Boyd <[email protected]>
Will
cover arm: perf: cleanups and initial refactoring
In reply to Mark RutlandHi Mark,
Quoted 20 lines · Mark Rutland
While reorganising the ARM perf backend to provide support for heterogeneous PMUs in big.LITTLE systems, I encountered a couple of issues requiring some preparatory work in addition to some opportunities for general cleanup in the backend. This series consists of those initial cleanups.
Currently the event mapping code in the ARM perf backend requires multi-dimensional tables to map from common event encodings to raw hardware values, where empty slots must be initialised to non-zero values. The current way of organising this results in very large support files which we can simplify with some macro use to remove a few hundred lines and make things more legible.
The PMU naming is somewhat of a mess, with most names not being supported by the perf tool. Given that no-one has complained, it seems that the PMUs are not being accessed by name in a perf context, and we can fix these to be consistent and usable with current tools. We update the OProfile name mangling to ensure that OProfile (which accesses the PMUs in its own namespace) are not adversely affected.
Quoted 3 lines
To prepare for reorganisation of the PMU probing code, new
platform_device_idvalues are added to allow ARMv6, ARMv7, and XScale PMUplatform_devicesto be distinguished.
I ran Vince Weaver's perf events test suite [1] against a kernel with these patches applied on an 8074 Dragonboard [2] and didn't see any regressions. The patches also look good to me.
1. https://github.com/deater/perf_event_tests
2. http://elinux.org/Dragonboard/APQ8074
Signature · 3 lines
Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation.
cover arm: perf: cleanups and initial refactoring
Quoted 27 lines · Christopher Covington
Hi Mark,
Quoted 20 lines · Mark Rutland
While reorganising the ARM perf backend to provide support for heterogeneous PMUs in big.LITTLE systems, I encountered a couple of issues requiring some preparatory work in addition to some opportunities for general cleanup in the backend. This series consists of those initial cleanups.
Currently the event mapping code in the ARM perf backend requires multi-dimensional tables to map from common event encodings to raw hardware values, where empty slots must be initialised to non-zero values. The current way of organising this results in very large support files which we can simplify with some macro use to remove a few hundred lines and make things more legible.
The PMU naming is somewhat of a mess, with most names not being supported by the perf tool. Given that no-one has complained, it seems that the PMUs are not being accessed by name in a perf context, and we can fix these to be consistent and usable with current tools. We update the OProfile name mangling to ensure that OProfile (which accesses the PMUs in its own namespace) are not adversely affected.
Quoted 3 lines
To prepare for reorganisation of the PMU probing code, new
platform_device_idvalues are added to allow ARMv6, ARMv7, and XScale PMUplatform_devicesto be distinguished.
Quoted 5 lines
I ran Vince Weaver's perf events test suite [1] against a kernel with these patches applied on an 8074 Dragonboard [2] and didn't see any regressions. The patches also look good to me.
Thanks for testing, Christopher!
Will