diff options
| author | Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com> | 2012-03-06 17:37:45 +0100 | 
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-03-07 09:40:50 +0000 | 
| commit | a0feb6db0fe03326d7d2c7a4615ce3289615c023 (patch) | |
| tree | 5252086b8224c588148af6a48618030aa6e4827a /arch/arm/kernel/perf_event.c | |
| parent | 3f31ae121348afd9ed39700ea2a63c17cd7eeed1 (diff) | |
| download | olio-linux-3.10-a0feb6db0fe03326d7d2c7a4615ce3289615c023.tar.xz olio-linux-3.10-a0feb6db0fe03326d7d2c7a4615ce3289615c023.zip  | |
ARM: 7358/1: perf: add PMU hotplug notifier
When a CPU is taken out of reset, either cold booted or hotplugged in,
some of its PMU registers can contain UNKNOWN values.
This patch adds a hotplug notifier to ARM core perf code so that upon
CPU restart the PMU unit is reset and becomes ready to use again.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/perf_event.c')
| -rw-r--r-- | arch/arm/kernel/perf_event.c | 23 | 
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 56173ae1644..b2abfa18f13 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -680,6 +680,28 @@ static void __init cpu_pmu_init(struct arm_pmu *armpmu)  }  /* + * PMU hardware loses all context when a CPU goes offline. + * When a CPU is hotplugged back in, since some hardware registers are + * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading + * junk values out of them. + */ +static int __cpuinit pmu_cpu_notify(struct notifier_block *b, +					unsigned long action, void *hcpu) +{ +	if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING) +		return NOTIFY_DONE; + +	if (cpu_pmu && cpu_pmu->reset) +		cpu_pmu->reset(NULL); + +	return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata pmu_cpu_notifier = { +	.notifier_call = pmu_cpu_notify, +}; + +/*   * CPU PMU identification and registration.   */  static int __init @@ -730,6 +752,7 @@ init_hw_perf_events(void)  		pr_info("enabled with %s PMU driver, %d counters available\n",  			cpu_pmu->name, cpu_pmu->num_events);  		cpu_pmu_init(cpu_pmu); +		register_cpu_notifier(&pmu_cpu_notifier);  		armpmu_register(cpu_pmu, "cpu", PERF_TYPE_RAW);  	} else {  		pr_info("no hardware support available\n");  |