aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/perf_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/kernel/perf_event.c')
-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 @@
16#include <linux/perf_event.h> 16#include <linux/perf_event.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <asm/arcregs.h> 18#include <asm/arcregs.h>
19#include <asm/stacktrace.h>
19 20
20struct arc_pmu { 21struct arc_pmu {
21 struct pmu pmu; 22 struct pmu pmu;
@@ -25,6 +26,34 @@ struct arc_pmu {
25 int ev_hw_idx[PERF_COUNT_ARC_HW_MAX]; 26 int ev_hw_idx[PERF_COUNT_ARC_HW_MAX];
26}; 27};
27 28
29struct arc_callchain_trace {
30 int depth;
31 void *perf_stuff;
32};
33
34static int callchain_trace(unsigned int addr, void *data)
35{
36 struct arc_callchain_trace *ctrl = data;
37 struct perf_callchain_entry *entry = ctrl->perf_stuff;
38 perf_callchain_store(entry, addr);
39
40 if (ctrl->depth++ < 3)
41 return 0;
42
43 return -1;
44}
45
46void
47perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
48{
49 struct arc_callchain_trace ctrl = {
50 .depth = 0,
51 .perf_stuff = entry,
52 };
53
54 arc_unwind_core(NULL, regs, callchain_trace, &ctrl);
55}
56
28static struct arc_pmu *arc_pmu; 57static struct arc_pmu *arc_pmu;
29 58
30/* read counter #idx; note that counter# != event# on ARC! */ 59/* read counter #idx; note that counter# != event# on ARC! */