[RFC PATCH 15/17] ARM: perf: use cpu pm notifiers to save pmu state
Lorenzo Pieralisi
lorenzo.pieralisi at arm.com
Thu Jul 7 11:50:28 EDT 2011
This patch integrates the new PM notifier chain into the perf driver
and provides code to execute proper callbacks when a CPU is powered down/up.
Since PMU registers are saved/restored on context switch a simple enable/disable
of PMU is enough to enter/exit lowpower.
v7 requires the counters to be disabled when the CPU comes out of reset since
some register values are UNKNOWN at reset; hence, when a CPU exits low power,
the perf driver reset function callback has to be executed.
Tested on dual core A9 with cores going through shut-down and reset, and
perf running a per cpu task through the "perf stat" command (perf stats
successfully checked against a normal run [power down disabled] through perf of
the same task).
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
---
arch/arm/kernel/perf_event.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index d53c0ab..9fd44a3 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -24,6 +24,7 @@
#include <asm/irq.h>
#include <asm/irq_regs.h>
#include <asm/pmu.h>
+#include <asm/cpu_pm.h>
#include <asm/stacktrace.h>
static struct platform_device *pmu_device;
@@ -623,6 +624,26 @@ static struct pmu pmu = {
#include "perf_event_v6.c"
#include "perf_event_v7.c"
+static int pmu_notifier(struct notifier_block *self, unsigned long cmd, void *v)
+{
+ switch (cmd) {
+ case CPU_PM_ENTER:
+ perf_pmu_disable(&pmu);
+ break;
+ case CPU_PM_ENTER_FAILED:
+ case CPU_PM_EXIT:
+ if (armpmu->reset)
+ armpmu->reset(NULL);
+ perf_pmu_enable(&pmu);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block pmu_notifier_block = {
+ .notifier_call = pmu_notifier,
+};
/*
* Ensure the PMU has sane values out of reset.
* This requires SMP to be available, so exists as a separate initcall.
@@ -682,6 +703,7 @@ init_hw_perf_events(void)
}
perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
+ cpu_pm_register_notifier(&pmu_notifier_block);
return 0;
}
--
1.7.4.4
More information about the linux-arm-kernel
mailing list