summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-11-12 11:00:03 +0100
committerVineet Gupta <vgupta@synopsys.com>2015-04-20 18:27:35 +0530
commit389e3160b9b0002f8e7c95e9c0af5da6da311892 (patch)
tree70a81d3823f2b8214be6d6afaaac763703c29ab1 /arch
parent0a8a47679351f00145ddeaa0a05b510e67b780be (diff)
ARC: perf: Add kernel callchain support
Signed-off-by: Mischa Jonker <mjonker@synopsys.com> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arc/kernel/perf_event.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c
index 181baeed4495..a6ad1e09e4be 100644
--- a/arch/arc/kernel/perf_event.c
+++ b/arch/arc/kernel/perf_event.c
@@ -16,6 +16,7 @@
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <asm/arcregs.h>
+#include <asm/stacktrace.h>
struct arc_pmu {
struct pmu pmu;
@@ -25,6 +26,34 @@ struct arc_pmu {
int ev_hw_idx[PERF_COUNT_ARC_HW_MAX];
};
+struct arc_callchain_trace {
+ int depth;
+ void *perf_stuff;
+};
+
+static int callchain_trace(unsigned int addr, void *data)
+{
+ struct arc_callchain_trace *ctrl = data;
+ struct perf_callchain_entry *entry = ctrl->perf_stuff;
+ perf_callchain_store(entry, addr);
+
+ if (ctrl->depth++ < 3)
+ return 0;
+
+ return -1;
+}
+
+void
+perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
+{
+ struct arc_callchain_trace ctrl = {
+ .depth = 0,
+ .perf_stuff = entry,
+ };
+
+ arc_unwind_core(NULL, regs, callchain_trace, &ctrl);
+}
+
static struct arc_pmu *arc_pmu;
/* read counter #idx; note that counter# != event# on ARC! */