Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8d17de3 authored by Neil Leeder's avatar Neil Leeder
Browse files

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: default avatarNeil Leeder <nleeder@codeaurora.org>
parent 4aa27647
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ static char *descriptions =
	" 8 Perf: arm64: Use device tree property for CTI PMU workaround\n"
	" 9 Perf: arm64: make request irq pmu-dependent\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,
+11 −8
Original line number Diff line number Diff line
@@ -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;
}
+2 −9
Original line number Diff line number Diff line
@@ -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];