From 580b7756c57e94e1b95d170594e0137607c75914 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Wed, 12 Dec 2012 18:13:44 +0000 Subject: ARM: perf: [WIP] Add a separate cpu_init() method for ARM PMUs We need a allocate some per-cpu-pmu data outside atomic context, along with other actions required for setting up the cpu_pmu struct. This code does not need to run on any particular CPU, so we call this after the per-CPU init method is called. Signed-off-by: Dave Martin --- arch/arm/include/asm/pmu.h | 1 + arch/arm/kernel/perf_event_cpu.c | 4 +++- arch/arm/kernel/perf_event_v7.c | 18 ++++++++++-------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index cb500631c00..b11a01a8c7c 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h @@ -110,6 +110,7 @@ struct arm_pmu { int (*map_event)(struct perf_event *event); void (*save_regs)(struct arm_pmu *, struct cpupmu_regs *); void (*restore_regs)(struct arm_pmu *, struct cpupmu_regs *); + void (*cpu_init)(struct arm_pmu *, struct arm_cpu_pmu *); int num_events; atomic_t active_events; struct mutex reserve_mutex; diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index 8b503bc6ee9..b2f202be922 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c @@ -162,6 +162,9 @@ static void cpu_pmu_init(struct arm_pmu *pmu) events->used_mask = cpu_pmu->used_mask; raw_spin_lock_init(&events->pmu_lock); + if (pmu->cpu_init) + pmu->cpu_init(pmu, cpu_pmu); + cpu_pmu->valid = true; } @@ -352,7 +355,6 @@ static int cpu_pmu_device_probe(struct platform_device *pdev) cpumask_copy(&sibling_mask, cpu_possible_mask); smp_call_function_any(&sibling_mask, init_fn, pmu, 1); - pmu->cpu_pmus = cpu_pmus; /* clobbered by init_fn */ /* now set the valid_cpus after init */ cpumask_copy(&pmu->valid_cpus, &sibling_mask); diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index cddaf6b9947..c860e1e2a86 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -1435,8 +1435,13 @@ static int armv7_a7_map_event(struct perf_event *event) &armv7_a7_perf_cache_map, 0xFF); } +static void armv7pmu_cpu_init(struct arm_pmu *pmu, + struct arm_cpu_pmu *cpupmu); + static void armv7pmu_init(struct arm_pmu *cpu_pmu) { + struct arm_cpu_pmu *cpu_pmus = cpu_pmu->cpu_pmus; + cpu_pmu->handle_irq = armv7pmu_handle_irq; cpu_pmu->enable = armv7pmu_enable_event; cpu_pmu->disable = armv7pmu_disable_event; @@ -1448,7 +1453,10 @@ static void armv7pmu_init(struct arm_pmu *cpu_pmu) cpu_pmu->reset = armv7pmu_reset; cpu_pmu->save_regs = armv7pmu_save_regs; cpu_pmu->restore_regs = armv7pmu_restore_regs; + cpu_pmu->cpu_init = armv7pmu_cpu_init; cpu_pmu->max_period = (1LLU << 32) - 1; + + cpu_pmu->cpu_pmus = cpu_pmus; }; static u32 armv7_read_num_pmnc_events(void) @@ -1463,10 +1471,9 @@ static u32 armv7_read_num_pmnc_events(void) return nb_cnt + 1; } -static void __v7_pmu_init_logical_state(struct arm_pmu *pmu) +static void armv7pmu_cpu_init(struct arm_pmu *pmu, + struct arm_cpu_pmu *cpupmu) { - struct arm_cpu_pmu *cpupmu = to_this_cpu_pmu(pmu); - size_t size = offsetof(struct armv7_pmu_logical_state, cntrs) + pmu->num_events * sizeof(*__v7_logical_state(cpupmu)); @@ -1495,7 +1502,6 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) cpu_pmu->name = "ARMv7 Cortex-A8"; cpu_pmu->map_event = armv7_a8_map_event; cpu_pmu->num_events = armv7_read_num_pmnc_events(); - __v7_pmu_init_logical_state(cpu_pmu); return 0; } @@ -1505,7 +1511,6 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu) cpu_pmu->name = "ARMv7 Cortex-A9"; cpu_pmu->map_event = armv7_a9_map_event; cpu_pmu->num_events = armv7_read_num_pmnc_events(); - __v7_pmu_init_logical_state(cpu_pmu); return 0; } @@ -1515,7 +1520,6 @@ static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu) cpu_pmu->name = "ARMv7 Cortex-A5"; cpu_pmu->map_event = armv7_a5_map_event; cpu_pmu->num_events = armv7_read_num_pmnc_events(); - __v7_pmu_init_logical_state(cpu_pmu); return 0; } @@ -1526,7 +1530,6 @@ static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu) 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; - __v7_pmu_init_logical_state(cpu_pmu); return 0; } @@ -1537,7 +1540,6 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu) 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; - __v7_pmu_init_logical_state(cpu_pmu); return 0; } #else -- cgit v1.2.3