Commit 4295b898 authored by Will Deacon's avatar Will Deacon Committed by Russell King

ARM: 7448/1: perf: remove arm_perf_pmu_ids global enumeration

In order to provide PMU name strings compatible with the OProfile
user ABI, an enumeration of all PMUs is currently used by perf to
identify each PMU uniquely. Unfortunately, this does not scale well
in the presence of multiple PMUs and creates a single, global namespace
across all PMUs in the system.

This patch removes the enumeration and instead uses the name string
for the PMU to map onto the OProfile variant. perf_pmu_name is
implemented for CPU PMUs, which is all that OProfile cares about anyway.
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 881ccccb
...@@ -12,21 +12,6 @@ ...@@ -12,21 +12,6 @@
#ifndef __ARM_PERF_EVENT_H__ #ifndef __ARM_PERF_EVENT_H__
#define __ARM_PERF_EVENT_H__ #define __ARM_PERF_EVENT_H__
/* ARM perf PMU IDs for use by internal perf clients. */ /* Nothing to see here... */
enum arm_perf_pmu_ids {
ARM_PERF_PMU_ID_XSCALE1 = 0,
ARM_PERF_PMU_ID_XSCALE2,
ARM_PERF_PMU_ID_V6,
ARM_PERF_PMU_ID_V6MP,
ARM_PERF_PMU_ID_CA8,
ARM_PERF_PMU_ID_CA9,
ARM_PERF_PMU_ID_CA5,
ARM_PERF_PMU_ID_CA15,
ARM_PERF_PMU_ID_CA7,
ARM_NUM_PMU_IDS,
};
extern enum arm_perf_pmu_ids
armpmu_get_pmu_id(void);
#endif /* __ARM_PERF_EVENT_H__ */ #endif /* __ARM_PERF_EVENT_H__ */
...@@ -103,10 +103,9 @@ struct pmu_hw_events { ...@@ -103,10 +103,9 @@ struct pmu_hw_events {
struct arm_pmu { struct arm_pmu {
struct pmu pmu; struct pmu pmu;
enum arm_perf_pmu_ids id;
enum arm_pmu_type type; enum arm_pmu_type type;
cpumask_t active_irqs; cpumask_t active_irqs;
const char *name; char *name;
irqreturn_t (*handle_irq)(int irq_num, void *dev); irqreturn_t (*handle_irq)(int irq_num, void *dev);
void (*enable)(struct hw_perf_event *evt, int idx); void (*enable)(struct hw_perf_event *evt, int idx);
void (*disable)(struct hw_perf_event *evt, int idx); void (*disable)(struct hw_perf_event *evt, int idx);
......
...@@ -47,17 +47,14 @@ static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); ...@@ -47,17 +47,14 @@ static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
/* Set at runtime when we know what CPU type we are. */ /* Set at runtime when we know what CPU type we are. */
static struct arm_pmu *cpu_pmu; static struct arm_pmu *cpu_pmu;
enum arm_perf_pmu_ids const char *perf_pmu_name(void)
armpmu_get_pmu_id(void)
{ {
int id = -ENODEV; if (!cpu_pmu)
return NULL;
if (cpu_pmu != NULL)
id = cpu_pmu->id;
return id; return cpu_pmu->pmu.name;
} }
EXPORT_SYMBOL_GPL(armpmu_get_pmu_id); EXPORT_SYMBOL_GPL(perf_pmu_name);
int perf_num_counters(void) int perf_num_counters(void)
{ {
...@@ -760,7 +757,7 @@ init_hw_perf_events(void) ...@@ -760,7 +757,7 @@ init_hw_perf_events(void)
cpu_pmu->name, cpu_pmu->num_events); cpu_pmu->name, cpu_pmu->num_events);
cpu_pmu_init(cpu_pmu); cpu_pmu_init(cpu_pmu);
register_cpu_notifier(&pmu_cpu_notifier); register_cpu_notifier(&pmu_cpu_notifier);
armpmu_register(cpu_pmu, "cpu", PERF_TYPE_RAW); armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW);
} else { } else {
pr_info("no hardware support available\n"); pr_info("no hardware support available\n");
} }
......
...@@ -650,7 +650,6 @@ static int armv6_map_event(struct perf_event *event) ...@@ -650,7 +650,6 @@ static int armv6_map_event(struct perf_event *event)
} }
static struct arm_pmu armv6pmu = { static struct arm_pmu armv6pmu = {
.id = ARM_PERF_PMU_ID_V6,
.name = "v6", .name = "v6",
.handle_irq = armv6pmu_handle_irq, .handle_irq = armv6pmu_handle_irq,
.enable = armv6pmu_enable_event, .enable = armv6pmu_enable_event,
...@@ -685,7 +684,6 @@ static int armv6mpcore_map_event(struct perf_event *event) ...@@ -685,7 +684,6 @@ static int armv6mpcore_map_event(struct perf_event *event)
} }
static struct arm_pmu armv6mpcore_pmu = { static struct arm_pmu armv6mpcore_pmu = {
.id = ARM_PERF_PMU_ID_V6MP,
.name = "v6mpcore", .name = "v6mpcore",
.handle_irq = armv6pmu_handle_irq, .handle_irq = armv6pmu_handle_irq,
.enable = armv6pmu_enable_event, .enable = armv6pmu_enable_event,
......
...@@ -1258,7 +1258,6 @@ static u32 __init armv7_read_num_pmnc_events(void) ...@@ -1258,7 +1258,6 @@ static u32 __init armv7_read_num_pmnc_events(void)
static struct arm_pmu *__init armv7_a8_pmu_init(void) static struct arm_pmu *__init armv7_a8_pmu_init(void)
{ {
armv7pmu.id = ARM_PERF_PMU_ID_CA8;
armv7pmu.name = "ARMv7 Cortex-A8"; armv7pmu.name = "ARMv7 Cortex-A8";
armv7pmu.map_event = armv7_a8_map_event; armv7pmu.map_event = armv7_a8_map_event;
armv7pmu.num_events = armv7_read_num_pmnc_events(); armv7pmu.num_events = armv7_read_num_pmnc_events();
...@@ -1267,7 +1266,6 @@ static struct arm_pmu *__init armv7_a8_pmu_init(void) ...@@ -1267,7 +1266,6 @@ static struct arm_pmu *__init armv7_a8_pmu_init(void)
static struct arm_pmu *__init armv7_a9_pmu_init(void) static struct arm_pmu *__init armv7_a9_pmu_init(void)
{ {
armv7pmu.id = ARM_PERF_PMU_ID_CA9;
armv7pmu.name = "ARMv7 Cortex-A9"; armv7pmu.name = "ARMv7 Cortex-A9";
armv7pmu.map_event = armv7_a9_map_event; armv7pmu.map_event = armv7_a9_map_event;
armv7pmu.num_events = armv7_read_num_pmnc_events(); armv7pmu.num_events = armv7_read_num_pmnc_events();
...@@ -1276,7 +1274,6 @@ static struct arm_pmu *__init armv7_a9_pmu_init(void) ...@@ -1276,7 +1274,6 @@ static struct arm_pmu *__init armv7_a9_pmu_init(void)
static struct arm_pmu *__init armv7_a5_pmu_init(void) static struct arm_pmu *__init armv7_a5_pmu_init(void)
{ {
armv7pmu.id = ARM_PERF_PMU_ID_CA5;
armv7pmu.name = "ARMv7 Cortex-A5"; armv7pmu.name = "ARMv7 Cortex-A5";
armv7pmu.map_event = armv7_a5_map_event; armv7pmu.map_event = armv7_a5_map_event;
armv7pmu.num_events = armv7_read_num_pmnc_events(); armv7pmu.num_events = armv7_read_num_pmnc_events();
...@@ -1285,7 +1282,6 @@ static struct arm_pmu *__init armv7_a5_pmu_init(void) ...@@ -1285,7 +1282,6 @@ static struct arm_pmu *__init armv7_a5_pmu_init(void)
static struct arm_pmu *__init armv7_a15_pmu_init(void) static struct arm_pmu *__init armv7_a15_pmu_init(void)
{ {
armv7pmu.id = ARM_PERF_PMU_ID_CA15;
armv7pmu.name = "ARMv7 Cortex-A15"; armv7pmu.name = "ARMv7 Cortex-A15";
armv7pmu.map_event = armv7_a15_map_event; armv7pmu.map_event = armv7_a15_map_event;
armv7pmu.num_events = armv7_read_num_pmnc_events(); armv7pmu.num_events = armv7_read_num_pmnc_events();
...@@ -1295,7 +1291,6 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void) ...@@ -1295,7 +1291,6 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
static struct arm_pmu *__init armv7_a7_pmu_init(void) static struct arm_pmu *__init armv7_a7_pmu_init(void)
{ {
armv7pmu.id = ARM_PERF_PMU_ID_CA7;
armv7pmu.name = "ARMv7 Cortex-A7"; armv7pmu.name = "ARMv7 Cortex-A7";
armv7pmu.map_event = armv7_a7_map_event; armv7pmu.map_event = armv7_a7_map_event;
armv7pmu.num_events = armv7_read_num_pmnc_events(); armv7pmu.num_events = armv7_read_num_pmnc_events();
......
...@@ -435,7 +435,6 @@ static int xscale_map_event(struct perf_event *event) ...@@ -435,7 +435,6 @@ static int xscale_map_event(struct perf_event *event)
} }
static struct arm_pmu xscale1pmu = { static struct arm_pmu xscale1pmu = {
.id = ARM_PERF_PMU_ID_XSCALE1,
.name = "xscale1", .name = "xscale1",
.handle_irq = xscale1pmu_handle_irq, .handle_irq = xscale1pmu_handle_irq,
.enable = xscale1pmu_enable_event, .enable = xscale1pmu_enable_event,
...@@ -803,7 +802,6 @@ xscale2pmu_write_counter(int counter, u32 val) ...@@ -803,7 +802,6 @@ xscale2pmu_write_counter(int counter, u32 val)
} }
static struct arm_pmu xscale2pmu = { static struct arm_pmu xscale2pmu = {
.id = ARM_PERF_PMU_ID_XSCALE2,
.name = "xscale2", .name = "xscale2",
.handle_irq = xscale2pmu_handle_irq, .handle_irq = xscale2pmu_handle_irq,
.enable = xscale2pmu_enable_event, .enable = xscale2pmu_enable_event,
......
...@@ -23,26 +23,37 @@ ...@@ -23,26 +23,37 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#ifdef CONFIG_HW_PERF_EVENTS #ifdef CONFIG_HW_PERF_EVENTS
/*
* OProfile has a curious naming scheme for the ARM PMUs, but they are
* part of the user ABI so we need to map from the perf PMU name for
* supported PMUs.
*/
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" },
};
char *op_name_from_perf_id(void) char *op_name_from_perf_id(void)
{ {
enum arm_perf_pmu_ids id = armpmu_get_pmu_id(); int i;
struct op_perf_name names;
switch (id) { const char *perf_name = perf_pmu_name();
case ARM_PERF_PMU_ID_XSCALE1:
return "arm/xscale1"; for (i = 0; i < ARRAY_SIZE(op_perf_name_map); ++i) {
case ARM_PERF_PMU_ID_XSCALE2: names = op_perf_name_map[i];
return "arm/xscale2"; if (!strcmp(names.perf_name, perf_name))
case ARM_PERF_PMU_ID_V6: return names.op_name;
return "arm/armv6";
case ARM_PERF_PMU_ID_V6MP:
return "arm/mpcore";
case ARM_PERF_PMU_ID_CA8:
return "arm/armv7";
case ARM_PERF_PMU_ID_CA9:
return "arm/armv7-ca9";
default:
return NULL;
} }
return NULL;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment