summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Leeder <nleeder@codeaurora.org>2014-10-01 13:29:57 -0400
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:48:18 -0700
commit94d0fa9c7cea0e4b2af18745823347d596a8603d (patch)
treed1d74bcb875d7840f238bb72e0780b85ef0bbe00
parente05cb5e6e5497c99937738a96737b6f91bf0322f (diff)
Perf: arm64: Refine disable/enable in tracecounters
Tracecounter code was not disabling counters as early as possible and enabling them as late as possible. Refine the logic so cycles spent inside the handler are lower. This results in more accurate per-process counter values. Change-Id: I5a83028da3c747c30a9e5a0ea3003638beadffec Signed-off-by: Neil Leeder <nleeder@codeaurora.org>
-rw-r--r--arch/arm64/kernel/perf_debug.c1
-rw-r--r--arch/arm64/kernel/perf_trace_counters.c19
-rw-r--r--arch/arm64/kernel/perf_trace_counters.h11
3 files changed, 14 insertions, 17 deletions
diff --git a/arch/arm64/kernel/perf_debug.c b/arch/arm64/kernel/perf_debug.c
index f4414c83e89f..3ad3e11d246b 100644
--- a/arch/arm64/kernel/perf_debug.c
+++ b/arch/arm64/kernel/perf_debug.c
@@ -28,6 +28,7 @@ static char *descriptions =
" 6 Perf: arm64: Add debugfs node to clear PMU\n"
" 7 Perf: arm64: Update PMU force reset\n"
"10 Perf: arm64: tracectr: initialize counts after hotplug\n"
+ "11 Perf: arm64: Refine disable/enable in tracecounters\n"
;
static ssize_t desc_read(struct file *fp, char __user *buf,
diff --git a/arch/arm64/kernel/perf_trace_counters.c b/arch/arm64/kernel/perf_trace_counters.c
index 779337a53a1e..ffcf3d00bd5d 100644
--- a/arch/arm64/kernel/perf_trace_counters.c
+++ b/arch/arm64/kernel/perf_trace_counters.c
@@ -19,6 +19,7 @@
static unsigned int tp_pid_state;
+DEFINE_PER_CPU(u32, cntenset_val);
DEFINE_PER_CPU(u32, previous_ccnt);
DEFINE_PER_CPU(u32[NUM_L1_CTRS], previous_l1_cnts);
DEFINE_PER_CPU(u32, old_pid);
@@ -39,14 +40,10 @@ static struct notifier_block tracectr_cpu_hotplug_notifier_block = {
.notifier_call = tracectr_cpu_hotplug_notifier,
};
-static void setup_prev_cnts(u32 cpu)
+static void setup_prev_cnts(u32 cpu, u32 cnten_val)
{
int i;
- u32 cnten_val;
- asm volatile("mrs %0, pmcntenset_el0" : "=r" (cnten_val));
- /* Disable all the counters that were enabled */
- asm volatile("msr pmcntenclr_el0, %0" : : "r" (cnten_val));
if (cnten_val & CC)
asm volatile("mrs %0, pmccntr_el0"
: "=r"(per_cpu(previous_ccnt, cpu)));
@@ -61,13 +58,12 @@ static void setup_prev_cnts(u32 cpu)
: "=r"(per_cpu(previous_l1_cnts[i], cpu)));
}
}
- /* Enable all the counters that were disabled */
- asm volatile("msr pmcntenset_el0, %0" : : "r" (cnten_val));
}
void tracectr_notifier(void *ignore, struct task_struct *prev,
struct task_struct *next)
{
+ u32 cnten_val;
int current_pid;
u32 cpu = task_thread_info(next)->cpu;
@@ -75,14 +71,21 @@ void tracectr_notifier(void *ignore, struct task_struct *prev,
return;
current_pid = next->pid;
if (per_cpu(old_pid, cpu) != -1) {
+ asm volatile("mrs %0, pmcntenset_el0" : "=r" (cnten_val));
+ per_cpu(cntenset_val, cpu) = cnten_val;
+ /* Disable all the counters that were enabled */
+ asm volatile("msr pmcntenclr_el0, %0" : : "r" (cnten_val));
if (per_cpu(hotplug_flag, cpu) == 1) {
per_cpu(hotplug_flag, cpu) = 0;
- setup_prev_cnts(cpu);
+ setup_prev_cnts(cpu, cnten_val);
} else {
trace_sched_switch_with_ctrs(per_cpu(old_pid, cpu),
current_pid);
}
+
+ /* Enable all the counters that were disabled */
+ asm volatile("msr pmcntenset_el0, %0" : : "r" (cnten_val));
}
per_cpu(old_pid, cpu) = current_pid;
}
diff --git a/arch/arm64/kernel/perf_trace_counters.h b/arch/arm64/kernel/perf_trace_counters.h
index b0cc9b8c6d13..d686e928e5df 100644
--- a/arch/arm64/kernel/perf_trace_counters.h
+++ b/arch/arm64/kernel/perf_trace_counters.h
@@ -29,6 +29,7 @@
#include <linux/cpumask.h>
#include <linux/tracepoint.h>
+DECLARE_PER_CPU(u32, cntenset_val);
DECLARE_PER_CPU(u32, previous_ccnt);
DECLARE_PER_CPU(u32[NUM_L1_CTRS], previous_l1_cnts);
TRACE_EVENT(sched_switch_with_ctrs,
@@ -59,13 +60,8 @@ TRACE_EVENT(sched_switch_with_ctrs,
__entry->old_pid = prev;
__entry->new_pid = next;
+ cnten_val = per_cpu(cntenset_val, cpu);
- /* Read PMCNTENSET */
- asm volatile("mrs %0, pmcntenset_el0"
- : "=r" (cnten_val));
- /* Disable all the counters that were enabled */
- asm volatile("msr pmcntenclr_el0, %0"
- : : "r" (cnten_val));
if (cnten_val & CC) {
asm volatile("mrs %0, pmccntr_el0"
: "=r" (total_ccnt));
@@ -90,9 +86,6 @@ TRACE_EVENT(sched_switch_with_ctrs,
} else
delta_l1_cnts[i] = 0;
}
- /* Enable all the counters that were disabled */
- asm volatile("msr pmcntenset_el0, %0"
- : : "r" (cnten_val));
__entry->ctr0 = delta_l1_cnts[0];
__entry->ctr1 = delta_l1_cnts[1];