diff options
author | Arnd Bergmann <arnd@arndb.de> | 2014-11-20 07:49:52 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2014-11-20 07:49:52 -0500 |
commit | b9e0e5a9e075575cc47940da8271d4908d3ae9c3 (patch) | |
tree | 1ad6cafc584265817fc7ff772dc6c27745c7e55d /arch/arm/include | |
parent | c3e6dc65f2ce83dacc0a18104bf44931e7eb8a5d (diff) | |
parent | af66abfe2ec8bd82211e9e4f036a64c902ff4cdb (diff) |
Merge tag 'arm-perf-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into next/drivers
Pull "ARM: perf: updates for 3.19" from Will Deacon:
This patch series takes us slightly further on the road to big.LITTLE
support in perf. The main change enabling this is moving the CCI PMU
driver away from the arm-pmu abstraction, allowing the arch code to
focus specifically on support for CPU PMUs.
* tag 'arm-perf-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux:
arm: perf: fold hotplug notifier into arm_pmu
arm: perf: dynamically allocate cpu hardware data
arm: perf: fold percpu_pmu into pmu_hw_events
arm: perf: kill get_hw_events()
arm: perf: limit size of accounting data
arm: perf: use IDR types for CPU PMUs
arm: perf: make PMU probing data-driven
arm: perf: add missing pr_info newlines
arm: perf: factor out callchain code
ARM: perf: use pr_* instead of printk
ARM: perf: remove useless return and check of idx in counter handling
bus: cci: move away from arm_pmu framework
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/perf_event.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/pmu.h | 36 |
2 files changed, 34 insertions, 4 deletions
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index c3a83691af8e..d9cf138fd7d4 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #ifndef __ARM_PERF_EVENT_H__ | 12 | #ifndef __ARM_PERF_EVENT_H__ |
13 | #define __ARM_PERF_EVENT_H__ | 13 | #define __ARM_PERF_EVENT_H__ |
14 | 14 | ||
15 | #ifdef CONFIG_HW_PERF_EVENTS | 15 | #ifdef CONFIG_PERF_EVENTS |
16 | struct pt_regs; | 16 | struct pt_regs; |
17 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs); | 17 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs); |
18 | extern unsigned long perf_misc_flags(struct pt_regs *regs); | 18 | extern unsigned long perf_misc_flags(struct pt_regs *regs); |
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 0b648c541293..b1596bd59129 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/perf_event.h> | 16 | #include <linux/perf_event.h> |
17 | 17 | ||
18 | #include <asm/cputype.h> | ||
19 | |||
18 | /* | 20 | /* |
19 | * struct arm_pmu_platdata - ARM PMU platform data | 21 | * struct arm_pmu_platdata - ARM PMU platform data |
20 | * | 22 | * |
@@ -66,19 +68,25 @@ struct pmu_hw_events { | |||
66 | /* | 68 | /* |
67 | * The events that are active on the PMU for the given index. | 69 | * The events that are active on the PMU for the given index. |
68 | */ | 70 | */ |
69 | struct perf_event **events; | 71 | struct perf_event *events[ARMPMU_MAX_HWEVENTS]; |
70 | 72 | ||
71 | /* | 73 | /* |
72 | * A 1 bit for an index indicates that the counter is being used for | 74 | * A 1 bit for an index indicates that the counter is being used for |
73 | * an event. A 0 means that the counter can be used. | 75 | * an event. A 0 means that the counter can be used. |
74 | */ | 76 | */ |
75 | unsigned long *used_mask; | 77 | DECLARE_BITMAP(used_mask, ARMPMU_MAX_HWEVENTS); |
76 | 78 | ||
77 | /* | 79 | /* |
78 | * Hardware lock to serialize accesses to PMU registers. Needed for the | 80 | * Hardware lock to serialize accesses to PMU registers. Needed for the |
79 | * read/modify/write sequences. | 81 | * read/modify/write sequences. |
80 | */ | 82 | */ |
81 | raw_spinlock_t pmu_lock; | 83 | raw_spinlock_t pmu_lock; |
84 | |||
85 | /* | ||
86 | * When using percpu IRQs, we need a percpu dev_id. Place it here as we | ||
87 | * already have to allocate this struct per cpu. | ||
88 | */ | ||
89 | struct arm_pmu *percpu_pmu; | ||
82 | }; | 90 | }; |
83 | 91 | ||
84 | struct arm_pmu { | 92 | struct arm_pmu { |
@@ -107,7 +115,8 @@ struct arm_pmu { | |||
107 | struct mutex reserve_mutex; | 115 | struct mutex reserve_mutex; |
108 | u64 max_period; | 116 | u64 max_period; |
109 | struct platform_device *plat_device; | 117 | struct platform_device *plat_device; |
110 | struct pmu_hw_events *(*get_hw_events)(void); | 118 | struct pmu_hw_events __percpu *hw_events; |
119 | struct notifier_block hotplug_nb; | ||
111 | }; | 120 | }; |
112 | 121 | ||
113 | #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) | 122 | #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) |
@@ -127,6 +136,27 @@ int armpmu_map_event(struct perf_event *event, | |||
127 | [PERF_COUNT_HW_CACHE_RESULT_MAX], | 136 | [PERF_COUNT_HW_CACHE_RESULT_MAX], |
128 | u32 raw_event_mask); | 137 | u32 raw_event_mask); |
129 | 138 | ||
139 | struct pmu_probe_info { | ||
140 | unsigned int cpuid; | ||
141 | unsigned int mask; | ||
142 | int (*init)(struct arm_pmu *); | ||
143 | }; | ||
144 | |||
145 | #define PMU_PROBE(_cpuid, _mask, _fn) \ | ||
146 | { \ | ||
147 | .cpuid = (_cpuid), \ | ||
148 | .mask = (_mask), \ | ||
149 | .init = (_fn), \ | ||
150 | } | ||
151 | |||
152 | #define ARM_PMU_PROBE(_cpuid, _fn) \ | ||
153 | PMU_PROBE(_cpuid, ARM_CPU_PART_MASK, _fn) | ||
154 | |||
155 | #define ARM_PMU_XSCALE_MASK ((0xff << 24) | ARM_CPU_XSCALE_ARCH_MASK) | ||
156 | |||
157 | #define XSCALE_PMU_PROBE(_version, _fn) \ | ||
158 | PMU_PROBE(ARM_CPU_IMP_INTEL << 24 | _version, ARM_PMU_XSCALE_MASK, _fn) | ||
159 | |||
130 | #endif /* CONFIG_HW_PERF_EVENTS */ | 160 | #endif /* CONFIG_HW_PERF_EVENTS */ |
131 | 161 | ||
132 | #endif /* __ARM_PMU_H__ */ | 162 | #endif /* __ARM_PMU_H__ */ |