aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2012-12-12 18:13:44 +0000
committerAndrey Konovalov <andrey.konovalov@linaro.org>2013-05-25 13:22:04 +0400
commit580b7756c57e94e1b95d170594e0137607c75914 (patch)
treeb6581367df618fd2b53d07db2744fe7312c233d4
parentc9547c4e2d1b1348ed74f62f607b8d913e9e6667 (diff)
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 <dave.martin@linaro.org>
-rw-r--r--arch/arm/include/asm/pmu.h1
-rw-r--r--arch/arm/kernel/perf_event_cpu.c4
-rw-r--r--arch/arm/kernel/perf_event_v7.c18
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