summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorNeil Leeder <nleeder@codeaurora.org>2014-10-30 13:17:08 -0400
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:58:10 -0700
commit0e4ee435ac293483d156db59cabb14a8445f5979 (patch)
tree04fd2eea5d09e732bdf5154b646e93cfe278f19c /arch
parent86cd54bb1953eaebbd8d466672851c545342ead0 (diff)
Perf: arm64: support hotplug and power collapse
Add notifiers for hotplug and power collapse in perf events. Preserve counters and user enables across these events. Disable and enable interrupts across events. This allows perf-events to be used in an environment where cores are power collapsing and being hotplugged. Change-Id: Id27ac3b1c0733677e0bc9740ce7534c3e5fdac7c Signed-off-by: Neil Leeder <nleeder@codeaurora.org> [satyap: merge conflict resolution and move changes in arch/arm64/kernel/perf_event.c to drivers/perf/arm_pmu.c to align with kernel 4.4] Signed-off-by: Satya Durga Srinivasu Prabhala <satyap@codeaurora.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm64/kernel/perf_debug.c1
-rw-r--r--arch/arm64/kernel/perf_event.c33
2 files changed, 33 insertions, 1 deletions
diff --git a/arch/arm64/kernel/perf_debug.c b/arch/arm64/kernel/perf_debug.c
index ef3313fd16c6..08e93a71fa7d 100644
--- a/arch/arm64/kernel/perf_debug.c
+++ b/arch/arm64/kernel/perf_debug.c
@@ -24,6 +24,7 @@
static char *descriptions =
" 0 arm64: perf: add debug patch logging framework\n"
" 1 Perf: arm64: Add L1 counters to tracepoints\n"
+ " 4 Perf: arm64: support hotplug and power collapse\n"
" 5 Perf: arm64: add perf user-mode permissions\n"
" 6 Perf: arm64: Add debugfs node to clear PMU\n"
" 7 Perf: arm64: Update PMU force reset\n"
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index a03c001a19e7..ce8eb8f565e1 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -25,6 +25,8 @@
#include <linux/perf/arm_pmu.h>
#include <linux/platform_device.h>
+static DEFINE_PER_CPU(u32, armv8_pm_pmuserenr);
+
/*
* ARMv8 PMUv3 Performance Events handling code.
* Common event types.
@@ -366,6 +368,7 @@ static void armv8pmu_enable_event(struct perf_event *event)
struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
int idx = hwc->idx;
+ u64 prev_count = local64_read(&hwc->prev_count);
/*
* Enable counter and interrupt, and set the counter to count
@@ -389,6 +392,11 @@ static void armv8pmu_enable_event(struct perf_event *event)
armv8pmu_enable_intens(idx);
/*
+ * Restore previous value
+ */
+ armv8pmu_write_counter(event, prev_count & 0xffffffff);
+
+ /*
* Enable counter
*/
armv8pmu_enable_counter(idx);
@@ -599,6 +607,27 @@ static int armv8_pmuv3_map_event(struct perf_event *event)
ARMV8_EVTYPE_EVENT);
}
+static void armv8pmu_save_pm_registers(void *hcpu)
+{
+ u32 val;
+ u64 lcpu = (u64)hcpu;
+ int cpu = (int)lcpu;
+
+ asm volatile("mrs %0, pmuserenr_el0" : "=r" (val));
+ per_cpu(armv8_pm_pmuserenr, cpu) = val;
+}
+
+static void armv8pmu_restore_pm_registers(void *hcpu)
+{
+ u32 val;
+ u64 lcpu = (u64)hcpu;
+ int cpu = (int)lcpu;
+
+ val = per_cpu(armv8_pm_pmuserenr, cpu);
+ if (val != 0)
+ asm volatile("msr pmuserenr_el0, %0" :: "r" (val));
+}
+
static int armv8_a53_map_event(struct perf_event *event)
{
return armpmu_map_event(event, &armv8_a53_perf_map,
@@ -642,6 +671,8 @@ void armv8_pmu_init(struct arm_pmu *cpu_pmu)
cpu_pmu->start = armv8pmu_start,
cpu_pmu->stop = armv8pmu_stop,
cpu_pmu->reset = armv8pmu_reset,
+ cpu_pmu->save_pm_registers = armv8pmu_save_pm_registers,
+ cpu_pmu->restore_pm_registers = armv8pmu_restore_pm_registers,
cpu_pmu->max_period = (1LLU << 32) - 1,
cpu_pmu->set_event_filter = armv8pmu_set_event_filter;
}
@@ -674,7 +705,7 @@ static const struct of_device_id armv8_pmu_of_device_ids[] = {
{.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init},
{.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init},
{.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init},
- {.compatible = "qcom,kryo-pmuv3", .data = kryo_pmu_init},
+ {.compatible = "qcom,kryo-pmuv3", .data = kryo_pmu_init},
{},
};