From: Ding Tianhong <dingtianhong@huawei.com>
To: Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will.deacon@arm.com>,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
"Paul Mackerras" <paulus@samba.org>,
Ingo Molnar <mingo@redhat.com>, Robert Richter <rric@kernel.org>,
Arnaldo Carvalho de Melo <acme@ghostprotocols.net>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
<oprofile-list@lists.sf.net>, Xinwei Hu <huxinwei@huawei.com>
Subject: [PATCH] arm64: add OProfile support
Date: Sat, 26 Apr 2014 16:38:23 +0800 [thread overview]
Message-ID: <535B707F.7020802@huawei.com> (raw)
Add OProfile support for arm64, using the perf backend, and failing back
to generic timer based sampling if PMU interrupt is not supported.
I have test this patch on Cortex-A53 and Cortex-A57 motherboard, the OProfile
could work well by PMU irq or arch timer irq.
Signed-off-by: Xinwei Hu <huxinwei@huawei.com>
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/Makefile | 2 +
arch/arm64/include/asm/stacktrace.h | 1 +
arch/arm64/kernel/perf_event.c | 13 ++++-
arch/arm64/oprofile/Makefile | 13 +++++
arch/arm64/oprofile/common.c | 106 ++++++++++++++++++++++++++++++++++++
6 files changed, 135 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/oprofile/Makefile
create mode 100644 arch/arm64/oprofile/common.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e6e4d37..f711445 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -40,6 +40,7 @@ config ARM64
select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_MEMBLOCK
select HAVE_PATA_PLATFORM
+ select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 2fceb71..6bb3d66 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -48,6 +48,8 @@ core-$(CONFIG_XEN) += arch/arm64/xen/
libs-y := arch/arm64/lib/ $(libs-y)
libs-y += $(LIBGCC)
+drivers-$(CONFIG_OPROFILE) += arch/arm64/oprofile/
+
# Default target when executing plain make
KBUILD_IMAGE := Image.gz
KBUILD_DTBS := dtbs
diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 7318f6d..fec7e84 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -19,6 +19,7 @@
struct stackframe {
unsigned long fp;
unsigned long sp;
+ unsigned long lr;
unsigned long pc;
};
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index baf5afb..a8fd1c1 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -51,6 +51,15 @@ static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
/* Set at runtime when we know what CPU type we are. */
static struct arm_pmu *cpu_pmu;
+const char *perf_pmu_name(void)
+{
+ if (!cpu_pmu)
+ return NULL;
+
+ return cpu_pmu->name;
+}
+EXPORT_SYMBOL_GPL(perf_pmu_name);
+
int
armpmu_get_max_events(void)
{
@@ -640,7 +649,7 @@ enum armv8_pmuv3_perf_types {
ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL = 0x03,
ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS = 0x04,
ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
- ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES = 0x11,
+ ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0x11,
ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED = 0x12,
/* At least one of the following is required. */
@@ -672,6 +681,8 @@ enum armv8_pmuv3_perf_types {
ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
+
+ ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES = 0XFF,
};
/* PMUv3 HW events mapping. */
diff --git a/arch/arm64/oprofile/Makefile b/arch/arm64/oprofile/Makefile
new file mode 100644
index 0000000..b2215c6
--- /dev/null
+++ b/arch/arm64/oprofile/Makefile
@@ -0,0 +1,13 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+ oprof.o cpu_buffer.o buffer_sync.o \
+ event_buffer.o oprofile_files.o \
+ oprofilefs.o oprofile_stats.o \
+ timer_int.o )
+
+ifeq ($(CONFIG_HW_PERF_EVENTS),y)
+DRIVER_OBJS += $(addprefix ../../../drivers/oprofile/, oprofile_perf.o)
+endif
+
+oprofile-y := $(DRIVER_OBJS) common.o
diff --git a/arch/arm64/oprofile/common.c b/arch/arm64/oprofile/common.c
new file mode 100644
index 0000000..7d1c19c
--- /dev/null
+++ b/arch/arm64/oprofile/common.c
@@ -0,0 +1,106 @@
+/**
+ * @file common.c
+ *
+ * @remark Copyright 2004 Oprofile Authors
+ * @remark Copyright 2010 ARM Ltd.
+ * @remark Read the file COPYING
+ *
+ * @author Zwane Mwaikambo
+ * @author Will Deacon [move to perf]
+ */
+
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/oprofile.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <asm/stacktrace.h>
+#include <linux/uaccess.h>
+
+#include <asm/perf_event.h>
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_HW_PERF_EVENTS
+
+char *op_name_from_perf_id(void)
+{
+ return perf_pmu_name();
+}
+#endif
+
+static int report_trace(struct stackframe *frame, void *d)
+{
+ unsigned int *depth = d;
+
+ if (*depth) {
+ oprofile_add_trace(frame->pc);
+ (*depth)--;
+ }
+
+ return *depth == 0;
+}
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ */
+struct frame_tail {
+ struct frame_tail *fp;
+ unsigned long sp;
+ unsigned long lr;
+} __attribute__((packed));
+
+static struct frame_tail *user_backtrace(struct frame_tail *tail)
+{
+ struct frame_tail buftail[2];
+
+ /* Also check accessibility of one struct frame_tail beyond */
+ if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+ return NULL;
+ if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
+ return NULL;
+
+ oprofile_add_trace(buftail[0].lr);
+
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (tail + 1 >= buftail[0].fp)
+ return NULL;
+
+ return buftail[0].fp-1;
+}
+
+static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+ struct frame_tail *tail = ((struct frame_tail *) regs->regs[29]) - 1;
+
+ if (!user_mode(regs)) {
+ struct stackframe frame;
+ frame.fp = regs->regs[29];
+ frame.sp = regs->sp;
+ frame.lr = regs->regs[30];
+ frame.pc = regs->pc;
+ walk_stackframe(&frame, report_trace, &depth);
+ return;
+ }
+
+ while (depth-- && tail && !((unsigned long) tail & 3))
+ tail = user_backtrace(tail);
+}
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+ /* provide backtrace support also in timer mode: */
+ ops->backtrace = arm_backtrace;
+
+ return oprofile_perf_init(ops);
+}
+
+void oprofile_arch_exit(void)
+{
+ oprofile_perf_exit();
+}
--
1.8.0
next reply other threads:[~2014-04-26 8:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-26 8:38 Ding Tianhong [this message]
2014-04-26 9:23 ` [PATCH] arm64: add OProfile support Catalin Marinas
2014-04-26 10:22 ` Ding Tianhong
2014-04-28 2:32 ` Ding Tianhong
2014-04-28 19:08 ` Will Deacon
[not found] ` <535EBC96.3090008@nc.rr.com>
2014-05-05 8:04 ` Ding Tianhong
2014-05-05 19:55 ` William Cohen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=535B707F.7020802@huawei.com \
--to=dingtianhong@huawei.com \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@ghostprotocols.net \
--cc=catalin.marinas@arm.com \
--cc=huxinwei@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=oprofile-list@lists.sf.net \
--cc=paulus@samba.org \
--cc=rric@kernel.org \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.