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

Commit 4e73e499 authored by Sheetal Sahasrabudhe's avatar Sheetal Sahasrabudhe Committed by Matt Wagantall
Browse files

Perf: arm64: Add debugfs node to clear PMU



Create debugfs node to clear PMU and some internal variables
used by Perf code. This provides the user with a recovery
path in case of PMU related unexpected error scenarios.

Change-Id: I4e62a51043d7dcaa21b551ce6a6715486ef46cca
Signed-off-by: default avatarSheetal Sahasrabudhe <sheetals@codeaurora.org>
parent 561bac78
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -465,6 +465,16 @@ config PERF_EVENTS_USERMODE

	  If you want user-mode programs to access perf events, say Y

config PERF_EVENTS_RESET_PMU_DEBUGFS
	bool "Reset PMU via debugfs node"
	depends on PERF_EVENTS
	help
		Enable the debugfs node that can be used to reset PMUs and all
		state variables associated with PMUs. If enabled, PMU and internal
		state variable are cleared.
		If you want to reset PMU and PMU related internal Perf variables
		via debugfs then say Y.

config SYS_SUPPORTS_HUGETLBFS
	def_bool y

+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ static char *descriptions =
	" 0 arm64: perf: add debug patch logging framework\n"
	" 1 Perf: arm64: Add L1 counters to tracepoints\n"
	" 5 Perf: arm64: add perf user-mode permissions\n"
	" 6 Perf: arm64: Add debugfs node to clear PMU\n"
;

static ssize_t desc_read(struct file *fp, char __user *buf,
+45 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/debugfs.h>

#include <asm/cputype.h>
#include <asm/irq.h>
@@ -1578,3 +1579,47 @@ unsigned long perf_misc_flags(struct pt_regs *regs)

	return misc;
}

#ifdef CONFIG_PERF_EVENTS_RESET_PMU_DEBUGFS
static void reset_pmu_force(void)
{
	if (cpu_pmu && cpu_pmu->reset)
		on_each_cpu(cpu_pmu->reset, NULL, 1);
	if (cpu_pmu && cpu_pmu->plat_device)
		armpmu_release_hardware(cpu_pmu);
}

static int write_enabled_perfpmu_action(void *data, u64 val)
{
	if (val != 0)
		reset_pmu_force();
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(fops_pmuaction,
		NULL, write_enabled_perfpmu_action, "%llu\n");

int __init init_pmu_actions(void)
{
	struct dentry *dir;
	struct dentry *file;
	unsigned int value = 1;

	dir = debugfs_create_dir("msm_perf", NULL);
	if (!dir)
		return -ENOMEM;
	file = debugfs_create_file("resetpmu", 0220, dir,
		&value, &fops_pmuaction);
	if (!file) {
		debugfs_remove(dir);
		return -ENOMEM;
	}
	return 0;
}
#else
int __init init_pmu_actions(void)
{
	return 0;
}
#endif
late_initcall(init_pmu_actions);