Linux-csky Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH V6 0/3] riscv: Add perf callchain support
@ 2019-08-29  6:56 Mao Han
  2019-08-29  6:57 ` [PATCH V6 1/3] " Mao Han
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Mao Han @ 2019-08-29  6:56 UTC (permalink / raw)
  To: linux-riscv
  Cc: linux-kernel, linux-csky, Mao Han, Paul Walmsley, Greentime Hu,
	Palmer Dabbelt, Christoph Hellwig, Guo Ren

This patch set add perf callchain(FP/DWARF) support for RISC-V.
It comes from the csky version callchain support with some
slight modifications. The patchset base on Linux 5.3-rc6.

Changes since v5:
  - use walk_stackframe from stacktrace.c to handle
    kernel callchain unwinding(fix invalid mem access)

Changes since v4:
  - Add missing PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
    verified with extra CFLAGS(-Wall -Werror)

Changes since v3:
  - Add more strict check for unwind_frame_kernel
  - update for kernel 5.3

Changes since v2:
  - fix inconsistent comment
  - force to build kernel with -fno-omit-frame-pointer if perf
    event is enabled

Changes since v1:
  - simplify implementation and code convention

Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: linux-riscv <linux-riscv@lists.infradead.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Guo Ren <guoren@kernel.org>

Mao Han (3):
  riscv: Add perf callchain support
  riscv: Add support for perf registers sampling
  riscv: Add support for libdw

 arch/riscv/Kconfig                            |  2 +
 arch/riscv/Makefile                           |  3 +
 arch/riscv/include/uapi/asm/perf_regs.h       | 42 ++++++++++++
 arch/riscv/kernel/Makefile                    |  4 +-
 arch/riscv/kernel/perf_callchain.c            | 95 ++++++++++++++++++++++++++
 arch/riscv/kernel/perf_regs.c                 | 44 ++++++++++++
 arch/riscv/kernel/stacktrace.c                |  2 +-
 tools/arch/riscv/include/uapi/asm/perf_regs.h | 42 ++++++++++++
 tools/perf/Makefile.config                    |  6 +-
 tools/perf/arch/riscv/Build                   |  1 +
 tools/perf/arch/riscv/Makefile                |  4 ++
 tools/perf/arch/riscv/include/perf_regs.h     | 96 +++++++++++++++++++++++++++
 tools/perf/arch/riscv/util/Build              |  2 +
 tools/perf/arch/riscv/util/dwarf-regs.c       | 72 ++++++++++++++++++++
 tools/perf/arch/riscv/util/unwind-libdw.c     | 57 ++++++++++++++++
 15 files changed, 469 insertions(+), 3 deletions(-)
 create mode 100644 arch/riscv/include/uapi/asm/perf_regs.h
 create mode 100644 arch/riscv/kernel/perf_callchain.c
 create mode 100644 arch/riscv/kernel/perf_regs.c
 create mode 100644 tools/arch/riscv/include/uapi/asm/perf_regs.h
 create mode 100644 tools/perf/arch/riscv/Build
 create mode 100644 tools/perf/arch/riscv/Makefile
 create mode 100644 tools/perf/arch/riscv/include/perf_regs.h
 create mode 100644 tools/perf/arch/riscv/util/Build
 create mode 100644 tools/perf/arch/riscv/util/dwarf-regs.c
 create mode 100644 tools/perf/arch/riscv/util/unwind-libdw.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V6 1/3] riscv: Add perf callchain support
  2019-08-29  6:56 [PATCH V6 0/3] riscv: Add perf callchain support Mao Han
@ 2019-08-29  6:57 ` " Mao Han
  2019-09-04 19:54   ` Paul Walmsley
  2019-08-29  6:57 ` [PATCH V6 2/3] riscv: Add support for perf registers sampling Mao Han
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Mao Han @ 2019-08-29  6:57 UTC (permalink / raw)
  To: linux-riscv
  Cc: linux-kernel, linux-csky, Mao Han, Paul Walmsley, Greentime Hu,
	Palmer Dabbelt, Christoph Hellwig, Guo Ren

This patch add support for perf callchain sampling on riscv platform.
The return address of leaf function is retrieved from pt_regs as
it is not saved in the outmost frame.

Signed-off-by: Mao Han <han_mao@c-sky.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: linux-riscv <linux-riscv@lists.infradead.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Guo Ren <guoren@kernel.org>
---
 arch/riscv/Makefile                |  3 ++
 arch/riscv/kernel/Makefile         |  3 +-
 arch/riscv/kernel/perf_callchain.c | 95 ++++++++++++++++++++++++++++++++++++++
 arch/riscv/kernel/stacktrace.c     |  2 +-
 4 files changed, 101 insertions(+), 2 deletions(-)
 create mode 100644 arch/riscv/kernel/perf_callchain.c

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 7a117be..946565b 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -54,6 +54,9 @@ endif
 ifeq ($(CONFIG_MODULE_SECTIONS),y)
 	KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/riscv/kernel/module.lds
 endif
+ifeq ($(CONFIG_PERF_EVENTS),y)
+        KBUILD_CFLAGS += -fno-omit-frame-pointer
+endif
 
 KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
 
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 2420d37..b1bea89 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_MODULE_SECTIONS)	+= module-sections.o
 obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= mcount-dyn.o
 
-obj-$(CONFIG_PERF_EVENTS)      += perf_event.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_callchain.o
 
 clean:
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
new file mode 100644
index 0000000..72168e1
--- /dev/null
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#include <linux/perf_event.h>
+#include <linux/uaccess.h>
+
+/* Kernel callchain */
+struct stackframe {
+	unsigned long fp;
+	unsigned long ra;
+};
+
+/*
+ * Get the return address for a single stackframe and return a pointer to the
+ * next frame tail.
+ */
+static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
+			unsigned long fp, unsigned long reg_ra)
+{
+	struct stackframe buftail;
+	unsigned long ra = 0;
+	unsigned long *user_frame_tail =
+			(unsigned long *)(fp - sizeof(struct stackframe));
+
+	/* Check accessibility of one struct frame_tail beyond */
+	if (!access_ok(user_frame_tail, sizeof(buftail)))
+		return 0;
+	if (__copy_from_user_inatomic(&buftail, user_frame_tail,
+				      sizeof(buftail)))
+		return 0;
+
+	if (reg_ra != 0)
+		ra = reg_ra;
+	else
+		ra = buftail.ra;
+
+	fp = buftail.fp;
+	if (ra != 0)
+		perf_callchain_store(entry, ra);
+	else
+		return 0;
+
+	return fp;
+}
+
+/*
+ * This will be called when the target is in user mode
+ * This function will only be called when we use
+ * "PERF_SAMPLE_CALLCHAIN" in
+ * kernel/events/core.c:perf_prepare_sample()
+ *
+ * How to trigger perf_callchain_[user/kernel] :
+ * $ perf record -e cpu-clock --call-graph fp ./program
+ * $ perf report --call-graph
+ *
+ * On RISC-V platform, the program being sampled and the C library
+ * need to be compiled with -fno-omit-frame-pointer, otherwise
+ * the user stack will not contain function frame.
+ */
+void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
+			 struct pt_regs *regs)
+{
+	unsigned long fp = 0;
+
+	/* RISC-V does not support perf in guest mode. */
+	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+		return;
+
+	fp = regs->s0;
+	perf_callchain_store(entry, regs->sepc);
+
+	fp = user_backtrace(entry, fp, regs->ra);
+	while (fp && !(fp & 0x3) && entry->nr < entry->max_stack)
+		fp = user_backtrace(entry, fp, 0);
+}
+
+bool fill_callchain(unsigned long pc, void *entry)
+{
+	return perf_callchain_store(entry, pc);
+}
+
+void notrace walk_stackframe(struct task_struct *task,
+	struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg);
+void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
+			   struct pt_regs *regs)
+{
+
+	/* RISC-V does not support perf in guest mode. */
+	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+		pr_warn("RISC-V does not support perf in guest mode!");
+		return;
+	}
+
+	walk_stackframe(NULL, regs, fill_callchain, entry);
+}
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
index f156427..9b376c1 100644
--- a/arch/riscv/kernel/stacktrace.c
+++ b/arch/riscv/kernel/stacktrace.c
@@ -19,7 +19,7 @@ struct stackframe {
 	unsigned long ra;
 };
 
-static void notrace walk_stackframe(struct task_struct *task,
+void notrace walk_stackframe(struct task_struct *task,
 	struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg)
 {
 	unsigned long fp, sp, pc;
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V6 2/3] riscv: Add support for perf registers sampling
  2019-08-29  6:56 [PATCH V6 0/3] riscv: Add perf callchain support Mao Han
  2019-08-29  6:57 ` [PATCH V6 1/3] " Mao Han
@ 2019-08-29  6:57 ` Mao Han
  2019-09-04 21:22   ` Paul Walmsley
  2019-08-29  6:57 ` [PATCH V6 3/3] riscv: Add support for libdw Mao Han
  2019-09-04  7:25 ` [PATCH V6 0/3] riscv: Add perf callchain support Greentime Hu
  3 siblings, 1 reply; 11+ messages in thread
From: Mao Han @ 2019-08-29  6:57 UTC (permalink / raw)
  To: linux-riscv
  Cc: linux-kernel, linux-csky, Mao Han, Paul Walmsley, Greentime Hu,
	Palmer Dabbelt, Christoph Hellwig, Guo Ren

This patch implements the perf registers sampling and validation API
for riscv arch. The valid registers and their register ID are defined in
perf_regs.h. Perf tool can backtrace in userspace with unwind library
and the registers/user stack dump support.

Signed-off-by: Mao Han <han_mao@c-sky.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: linux-riscv <linux-riscv@lists.infradead.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Guo Ren <guoren@kernel.org>
---
 arch/riscv/Kconfig                      |  2 ++
 arch/riscv/include/uapi/asm/perf_regs.h | 42 +++++++++++++++++++++++++++++++
 arch/riscv/kernel/Makefile              |  1 +
 arch/riscv/kernel/perf_regs.c           | 44 +++++++++++++++++++++++++++++++++
 4 files changed, 89 insertions(+)
 create mode 100644 arch/riscv/include/uapi/asm/perf_regs.h
 create mode 100644 arch/riscv/kernel/perf_regs.c

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 59a4727..4bc976d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -35,6 +35,8 @@ config RISCV
 	select HAVE_DMA_CONTIGUOUS
 	select HAVE_FUTEX_CMPXCHG if FUTEX
 	select HAVE_PERF_EVENTS
+	select HAVE_PERF_REGS
+	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_SYSCALL_TRACEPOINTS
 	select IRQ_DOMAIN
 	select SPARSE_IRQ
diff --git a/arch/riscv/include/uapi/asm/perf_regs.h b/arch/riscv/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000..df1a581
--- /dev/null
+++ b/arch/riscv/include/uapi/asm/perf_regs.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#ifndef _ASM_RISCV_PERF_REGS_H
+#define _ASM_RISCV_PERF_REGS_H
+
+enum perf_event_riscv_regs {
+	PERF_REG_RISCV_PC,
+	PERF_REG_RISCV_RA,
+	PERF_REG_RISCV_SP,
+	PERF_REG_RISCV_GP,
+	PERF_REG_RISCV_TP,
+	PERF_REG_RISCV_T0,
+	PERF_REG_RISCV_T1,
+	PERF_REG_RISCV_T2,
+	PERF_REG_RISCV_S0,
+	PERF_REG_RISCV_S1,
+	PERF_REG_RISCV_A0,
+	PERF_REG_RISCV_A1,
+	PERF_REG_RISCV_A2,
+	PERF_REG_RISCV_A3,
+	PERF_REG_RISCV_A4,
+	PERF_REG_RISCV_A5,
+	PERF_REG_RISCV_A6,
+	PERF_REG_RISCV_A7,
+	PERF_REG_RISCV_S2,
+	PERF_REG_RISCV_S3,
+	PERF_REG_RISCV_S4,
+	PERF_REG_RISCV_S5,
+	PERF_REG_RISCV_S6,
+	PERF_REG_RISCV_S7,
+	PERF_REG_RISCV_S8,
+	PERF_REG_RISCV_S9,
+	PERF_REG_RISCV_S10,
+	PERF_REG_RISCV_S11,
+	PERF_REG_RISCV_T3,
+	PERF_REG_RISCV_T4,
+	PERF_REG_RISCV_T5,
+	PERF_REG_RISCV_T6,
+	PERF_REG_RISCV_MAX,
+};
+#endif /* _ASM_RISCV_PERF_REGS_H */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index b1bea89..696020f 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -40,5 +40,6 @@ obj-$(CONFIG_DYNAMIC_FTRACE)	+= mcount-dyn.o
 
 obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_callchain.o
+obj-$(CONFIG_HAVE_PERF_REGS)	+= perf_regs.o
 
 clean:
diff --git a/arch/riscv/kernel/perf_regs.c b/arch/riscv/kernel/perf_regs.c
new file mode 100644
index 0000000..04a38fb
--- /dev/null
+++ b/arch/riscv/kernel/perf_regs.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+	if (WARN_ON_ONCE((u32)idx >= PERF_REG_RISCV_MAX))
+		return 0;
+
+	return ((unsigned long *)regs)[idx];
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_RISCV_MAX) - 1))
+
+int perf_reg_validate(u64 mask)
+{
+	if (!mask || mask & REG_RESERVED)
+		return -EINVAL;
+
+	return 0;
+}
+
+u64 perf_reg_abi(struct task_struct *task)
+{
+#if __riscv_xlen == 64
+	return PERF_SAMPLE_REGS_ABI_64;
+#else
+	return PERF_SAMPLE_REGS_ABI_32;
+#endif
+}
+
+void perf_get_regs_user(struct perf_regs *regs_user,
+			struct pt_regs *regs,
+			struct pt_regs *regs_user_copy)
+{
+	regs_user->regs = task_pt_regs(current);
+	regs_user->abi = perf_reg_abi(current);
+}
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH V6 3/3] riscv: Add support for libdw
  2019-08-29  6:56 [PATCH V6 0/3] riscv: Add perf callchain support Mao Han
  2019-08-29  6:57 ` [PATCH V6 1/3] " Mao Han
  2019-08-29  6:57 ` [PATCH V6 2/3] riscv: Add support for perf registers sampling Mao Han
@ 2019-08-29  6:57 ` Mao Han
  2019-09-04 21:24   ` Paul Walmsley
  2019-09-04  7:25 ` [PATCH V6 0/3] riscv: Add perf callchain support Greentime Hu
  3 siblings, 1 reply; 11+ messages in thread
From: Mao Han @ 2019-08-29  6:57 UTC (permalink / raw)
  To: linux-riscv
  Cc: linux-kernel, linux-csky, Mao Han, Paul Walmsley, Greentime Hu,
	Palmer Dabbelt, Christoph Hellwig, Guo Ren

This patch add support for DWARF register mappings and libdw registers
initialization, which is used by perf callchain analyzing when
--call-graph=dwarf is given.

Signed-off-by: Mao Han <han_mao@c-sky.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: linux-riscv <linux-riscv@lists.infradead.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Guo Ren <guoren@kernel.org>
---
 tools/arch/riscv/include/uapi/asm/perf_regs.h | 42 ++++++++++++
 tools/perf/Makefile.config                    |  6 +-
 tools/perf/arch/riscv/Build                   |  1 +
 tools/perf/arch/riscv/Makefile                |  4 ++
 tools/perf/arch/riscv/include/perf_regs.h     | 96 +++++++++++++++++++++++++++
 tools/perf/arch/riscv/util/Build              |  2 +
 tools/perf/arch/riscv/util/dwarf-regs.c       | 72 ++++++++++++++++++++
 tools/perf/arch/riscv/util/unwind-libdw.c     | 57 ++++++++++++++++
 8 files changed, 279 insertions(+), 1 deletion(-)
 create mode 100644 tools/arch/riscv/include/uapi/asm/perf_regs.h
 create mode 100644 tools/perf/arch/riscv/Build
 create mode 100644 tools/perf/arch/riscv/Makefile
 create mode 100644 tools/perf/arch/riscv/include/perf_regs.h
 create mode 100644 tools/perf/arch/riscv/util/Build
 create mode 100644 tools/perf/arch/riscv/util/dwarf-regs.c
 create mode 100644 tools/perf/arch/riscv/util/unwind-libdw.c

diff --git a/tools/arch/riscv/include/uapi/asm/perf_regs.h b/tools/arch/riscv/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000..df1a581
--- /dev/null
+++ b/tools/arch/riscv/include/uapi/asm/perf_regs.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#ifndef _ASM_RISCV_PERF_REGS_H
+#define _ASM_RISCV_PERF_REGS_H
+
+enum perf_event_riscv_regs {
+	PERF_REG_RISCV_PC,
+	PERF_REG_RISCV_RA,
+	PERF_REG_RISCV_SP,
+	PERF_REG_RISCV_GP,
+	PERF_REG_RISCV_TP,
+	PERF_REG_RISCV_T0,
+	PERF_REG_RISCV_T1,
+	PERF_REG_RISCV_T2,
+	PERF_REG_RISCV_S0,
+	PERF_REG_RISCV_S1,
+	PERF_REG_RISCV_A0,
+	PERF_REG_RISCV_A1,
+	PERF_REG_RISCV_A2,
+	PERF_REG_RISCV_A3,
+	PERF_REG_RISCV_A4,
+	PERF_REG_RISCV_A5,
+	PERF_REG_RISCV_A6,
+	PERF_REG_RISCV_A7,
+	PERF_REG_RISCV_S2,
+	PERF_REG_RISCV_S3,
+	PERF_REG_RISCV_S4,
+	PERF_REG_RISCV_S5,
+	PERF_REG_RISCV_S6,
+	PERF_REG_RISCV_S7,
+	PERF_REG_RISCV_S8,
+	PERF_REG_RISCV_S9,
+	PERF_REG_RISCV_S10,
+	PERF_REG_RISCV_S11,
+	PERF_REG_RISCV_T3,
+	PERF_REG_RISCV_T4,
+	PERF_REG_RISCV_T5,
+	PERF_REG_RISCV_T6,
+	PERF_REG_RISCV_MAX,
+};
+#endif /* _ASM_RISCV_PERF_REGS_H */
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 89ac5a1..eaf25ee 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -60,6 +60,10 @@ ifeq ($(SRCARCH),arm64)
   LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
 endif
 
+ifeq ($(SRCARCH),riscv)
+  NO_PERF_REGS := 0
+endif
+
 ifeq ($(SRCARCH),csky)
   NO_PERF_REGS := 0
 endif
@@ -82,7 +86,7 @@ endif
 # Disable it on all other architectures in case libdw unwind
 # support is detected in system. Add supported architectures
 # to the check.
-ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky))
+ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky riscv))
   NO_LIBDW_DWARF_UNWIND := 1
 endif
 
diff --git a/tools/perf/arch/riscv/Build b/tools/perf/arch/riscv/Build
new file mode 100644
index 0000000..e4e5f33
--- /dev/null
+++ b/tools/perf/arch/riscv/Build
@@ -0,0 +1 @@
+perf-y += util/
diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
new file mode 100644
index 0000000..1aa9dd7
--- /dev/null
+++ b/tools/perf/arch/riscv/Makefile
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+endif
+PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
diff --git a/tools/perf/arch/riscv/include/perf_regs.h b/tools/perf/arch/riscv/include/perf_regs.h
new file mode 100644
index 0000000..7a8bcde
--- /dev/null
+++ b/tools/perf/arch/riscv/include/perf_regs.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include <stdlib.h>
+#include <linux/types.h>
+#include <asm/perf_regs.h>
+
+#define PERF_REGS_MASK	((1ULL << PERF_REG_RISCV_MAX) - 1)
+#define PERF_REGS_MAX	PERF_REG_RISCV_MAX
+#if __riscv_xlen == 64
+#define PERF_SAMPLE_REGS_ABI    PERF_SAMPLE_REGS_ABI_64
+#else
+#define PERF_SAMPLE_REGS_ABI	PERF_SAMPLE_REGS_ABI_32
+#endif
+
+#define PERF_REG_IP	PERF_REG_RISCV_PC
+#define PERF_REG_SP	PERF_REG_RISCV_SP
+
+static inline const char *perf_reg_name(int id)
+{
+	switch (id) {
+	case PERF_REG_RISCV_PC:
+		return "pc";
+	case PERF_REG_RISCV_RA:
+		return "ra";
+	case PERF_REG_RISCV_SP:
+		return "sp";
+	case PERF_REG_RISCV_GP:
+		return "gp";
+	case PERF_REG_RISCV_TP:
+		return "tp";
+	case PERF_REG_RISCV_T0:
+		return "t0";
+	case PERF_REG_RISCV_T1:
+		return "t1";
+	case PERF_REG_RISCV_T2:
+		return "t2";
+	case PERF_REG_RISCV_S0:
+		return "s0";
+	case PERF_REG_RISCV_S1:
+		return "s1";
+	case PERF_REG_RISCV_A0:
+		return "a0";
+	case PERF_REG_RISCV_A1:
+		return "a1";
+	case PERF_REG_RISCV_A2:
+		return "a2";
+	case PERF_REG_RISCV_A3:
+		return "a3";
+	case PERF_REG_RISCV_A4:
+		return "a4";
+	case PERF_REG_RISCV_A5:
+		return "a5";
+	case PERF_REG_RISCV_A6:
+		return "a6";
+	case PERF_REG_RISCV_A7:
+		return "a7";
+	case PERF_REG_RISCV_S2:
+		return "s2";
+	case PERF_REG_RISCV_S3:
+		return "s3";
+	case PERF_REG_RISCV_S4:
+		return "s4";
+	case PERF_REG_RISCV_S5:
+		return "s5";
+	case PERF_REG_RISCV_S6:
+		return "s6";
+	case PERF_REG_RISCV_S7:
+		return "s7";
+	case PERF_REG_RISCV_S8:
+		return "s8";
+	case PERF_REG_RISCV_S9:
+		return "s9";
+	case PERF_REG_RISCV_S10:
+		return "s10";
+	case PERF_REG_RISCV_S11:
+		return "s11";
+	case PERF_REG_RISCV_T3:
+		return "t3";
+	case PERF_REG_RISCV_T4:
+		return "t4";
+	case PERF_REG_RISCV_T5:
+		return "t5";
+	case PERF_REG_RISCV_T6:
+		return "t6";
+	default:
+		return NULL;
+	}
+
+	return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
new file mode 100644
index 0000000..1160bb2
--- /dev/null
+++ b/tools/perf/arch/riscv/util/Build
@@ -0,0 +1,2 @@
+perf-$(CONFIG_DWARF) += dwarf-regs.o
+perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/arch/riscv/util/dwarf-regs.c b/tools/perf/arch/riscv/util/dwarf-regs.c
new file mode 100644
index 0000000..f3555f6
--- /dev/null
+++ b/tools/perf/arch/riscv/util/dwarf-regs.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd.
+ * Mapping of DWARF debug register numbers into register names.
+ */
+
+#include <stddef.h>
+#include <errno.h> /* for EINVAL */
+#include <string.h> /* for strcmp */
+#include <dwarf-regs.h>
+
+struct pt_regs_dwarfnum {
+	const char *name;
+	unsigned int dwarfnum;
+};
+
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+struct pt_regs_dwarfnum riscv_dwarf_regs_table[] = {
+	REG_DWARFNUM_NAME("%zero", 0),
+	REG_DWARFNUM_NAME("%ra", 1),
+	REG_DWARFNUM_NAME("%sp", 2),
+	REG_DWARFNUM_NAME("%gp", 3),
+	REG_DWARFNUM_NAME("%tp", 4),
+	REG_DWARFNUM_NAME("%t0", 5),
+	REG_DWARFNUM_NAME("%t1", 6),
+	REG_DWARFNUM_NAME("%t2", 7),
+	REG_DWARFNUM_NAME("%s0", 8),
+	REG_DWARFNUM_NAME("%s1", 9),
+	REG_DWARFNUM_NAME("%a0", 10),
+	REG_DWARFNUM_NAME("%a1", 11),
+	REG_DWARFNUM_NAME("%a2", 12),
+	REG_DWARFNUM_NAME("%a3", 13),
+	REG_DWARFNUM_NAME("%a4", 14),
+	REG_DWARFNUM_NAME("%a5", 15),
+	REG_DWARFNUM_NAME("%a6", 16),
+	REG_DWARFNUM_NAME("%a7", 17),
+	REG_DWARFNUM_NAME("%s2", 18),
+	REG_DWARFNUM_NAME("%s3", 19),
+	REG_DWARFNUM_NAME("%s4", 20),
+	REG_DWARFNUM_NAME("%s5", 21),
+	REG_DWARFNUM_NAME("%s6", 22),
+	REG_DWARFNUM_NAME("%s7", 23),
+	REG_DWARFNUM_NAME("%s8", 24),
+	REG_DWARFNUM_NAME("%s9", 25),
+	REG_DWARFNUM_NAME("%s10", 26),
+	REG_DWARFNUM_NAME("%s11", 27),
+	REG_DWARFNUM_NAME("%t3", 28),
+	REG_DWARFNUM_NAME("%t4", 29),
+	REG_DWARFNUM_NAME("%t5", 30),
+	REG_DWARFNUM_NAME("%t6", 31),
+	REG_DWARFNUM_END,
+};
+
+#define RISCV_MAX_REGS ((sizeof(riscv_dwarf_regs_table) / \
+		 sizeof(riscv_dwarf_regs_table[0])) - 1)
+
+const char *get_arch_regstr(unsigned int n)
+{
+	return (n < RISCV_MAX_REGS) ? riscv_dwarf_regs_table[n].name : NULL;
+}
+
+int regs_query_register_offset(const char *name)
+{
+	const struct pt_regs_dwarfnum *roff;
+
+	for (roff = riscv_dwarf_regs_table; roff->name != NULL; roff++)
+		if (!strcmp(roff->name, name))
+			return roff->dwarfnum;
+	return -EINVAL;
+}
diff --git a/tools/perf/arch/riscv/util/unwind-libdw.c b/tools/perf/arch/riscv/util/unwind-libdw.c
new file mode 100644
index 0000000..19536e1
--- /dev/null
+++ b/tools/perf/arch/riscv/util/unwind-libdw.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#include <elfutils/libdwfl.h>
+#include "../../util/unwind-libdw.h"
+#include "../../util/perf_regs.h"
+#include "../../util/event.h"
+
+bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
+{
+	struct unwind_info *ui = arg;
+	struct regs_dump *user_regs = &ui->sample->user_regs;
+	Dwarf_Word dwarf_regs[32];
+
+#define REG(r) ({						\
+	Dwarf_Word val = 0;					\
+	perf_reg_value(&val, user_regs, PERF_REG_RISCV_##r);	\
+	val;							\
+})
+
+	dwarf_regs[0]  = 0;
+	dwarf_regs[1]  = REG(RA);
+	dwarf_regs[2]  = REG(SP);
+	dwarf_regs[3]  = REG(GP);
+	dwarf_regs[4]  = REG(TP);
+	dwarf_regs[5]  = REG(T0);
+	dwarf_regs[6]  = REG(T1);
+	dwarf_regs[7]  = REG(T2);
+	dwarf_regs[8]  = REG(S0);
+	dwarf_regs[9]  = REG(S1);
+	dwarf_regs[10] = REG(A0);
+	dwarf_regs[11] = REG(A1);
+	dwarf_regs[12] = REG(A2);
+	dwarf_regs[13] = REG(A3);
+	dwarf_regs[14] = REG(A4);
+	dwarf_regs[15] = REG(A5);
+	dwarf_regs[16] = REG(A6);
+	dwarf_regs[17] = REG(A7);
+	dwarf_regs[18] = REG(S2);
+	dwarf_regs[19] = REG(S3);
+	dwarf_regs[20] = REG(S4);
+	dwarf_regs[21] = REG(S5);
+	dwarf_regs[22] = REG(S6);
+	dwarf_regs[23] = REG(S7);
+	dwarf_regs[24] = REG(S8);
+	dwarf_regs[25] = REG(S9);
+	dwarf_regs[26] = REG(S10);
+	dwarf_regs[27] = REG(S11);
+	dwarf_regs[28] = REG(T3);
+	dwarf_regs[29] = REG(T4);
+	dwarf_regs[30] = REG(T5);
+	dwarf_regs[31] = REG(T6);
+	dwfl_thread_state_register_pc(thread, REG(PC));
+
+	return dwfl_thread_state_registers(thread, 0, PERF_REG_RISCV_MAX,
+					   dwarf_regs);
+}
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH V6 0/3] riscv: Add perf callchain support
  2019-08-29  6:56 [PATCH V6 0/3] riscv: Add perf callchain support Mao Han
                   ` (2 preceding siblings ...)
  2019-08-29  6:57 ` [PATCH V6 3/3] riscv: Add support for libdw Mao Han
@ 2019-09-04  7:25 ` Greentime Hu
  2019-09-04 12:20   ` Guo Ren
  3 siblings, 1 reply; 11+ messages in thread
From: Greentime Hu @ 2019-09-04  7:25 UTC (permalink / raw)
  To: Mao Han, greentime.hu
  Cc: linux-riscv, Linux Kernel Mailing List, linux-csky,
	Paul Walmsley, Palmer Dabbelt, Christoph Hellwig, Guo Ren

Mao Han <han_mao@c-sky.com> 於 2019年8月29日 週四 下午2:57寫道:
>
> This patch set add perf callchain(FP/DWARF) support for RISC-V.
> It comes from the csky version callchain support with some
> slight modifications. The patchset base on Linux 5.3-rc6.
>
> Changes since v5:
>   - use walk_stackframe from stacktrace.c to handle
>     kernel callchain unwinding(fix invalid mem access)
>
> Changes since v4:
>   - Add missing PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
>     verified with extra CFLAGS(-Wall -Werror)
>
> Changes since v3:
>   - Add more strict check for unwind_frame_kernel
>   - update for kernel 5.3
>
> Changes since v2:
>   - fix inconsistent comment
>   - force to build kernel with -fno-omit-frame-pointer if perf
>     event is enabled
>
> Changes since v1:
>   - simplify implementation and code convention
>
> Cc: Paul Walmsley <paul.walmsley@sifive.com>
> Cc: Greentime Hu <green.hu@gmail.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Cc: linux-riscv <linux-riscv@lists.infradead.org>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Guo Ren <guoren@kernel.org>
>
> Mao Han (3):
>   riscv: Add perf callchain support
>   riscv: Add support for perf registers sampling
>   riscv: Add support for libdw
>
>  arch/riscv/Kconfig                            |  2 +
>  arch/riscv/Makefile                           |  3 +
>  arch/riscv/include/uapi/asm/perf_regs.h       | 42 ++++++++++++
>  arch/riscv/kernel/Makefile                    |  4 +-
>  arch/riscv/kernel/perf_callchain.c            | 95 ++++++++++++++++++++++++++
>  arch/riscv/kernel/perf_regs.c                 | 44 ++++++++++++
>  arch/riscv/kernel/stacktrace.c                |  2 +-
>  tools/arch/riscv/include/uapi/asm/perf_regs.h | 42 ++++++++++++
>  tools/perf/Makefile.config                    |  6 +-
>  tools/perf/arch/riscv/Build                   |  1 +
>  tools/perf/arch/riscv/Makefile                |  4 ++
>  tools/perf/arch/riscv/include/perf_regs.h     | 96 +++++++++++++++++++++++++++
>  tools/perf/arch/riscv/util/Build              |  2 +
>  tools/perf/arch/riscv/util/dwarf-regs.c       | 72 ++++++++++++++++++++
>  tools/perf/arch/riscv/util/unwind-libdw.c     | 57 ++++++++++++++++
>  15 files changed, 469 insertions(+), 3 deletions(-)
>  create mode 100644 arch/riscv/include/uapi/asm/perf_regs.h
>  create mode 100644 arch/riscv/kernel/perf_callchain.c
>  create mode 100644 arch/riscv/kernel/perf_regs.c
>  create mode 100644 tools/arch/riscv/include/uapi/asm/perf_regs.h
>  create mode 100644 tools/perf/arch/riscv/Build
>  create mode 100644 tools/perf/arch/riscv/Makefile
>  create mode 100644 tools/perf/arch/riscv/include/perf_regs.h
>  create mode 100644 tools/perf/arch/riscv/util/Build
>  create mode 100644 tools/perf/arch/riscv/util/dwarf-regs.c
>  create mode 100644 tools/perf/arch/riscv/util/unwind-libdw.c
>

Tested-by: Greentime Hu <greentime.hu@sifive.com>

I tested this patchset based on v5.3-rc6 and it can use dwarf or fp to
backtrace in Unleashed board.

# perf record -e cpu-clock --call-graph dwarf ls -l /
total 4
drwxr-xr-x    2 root     root             0 Aug 26  2019 bin
drwxr-xr-x    5 root     root         12720 Jan  1 00:00 dev
drwxr-xr-x    5 root     root             0 Jan  1 00:00 etc
-rwxr-xr-x    1 root     root           178 Aug 26  2019 init
drwxr-xr-x    2 root     root             0 Aug 26  2019 lib
lrwxrwxrwx    1 root     root             3 Aug 19  2019 lib64 -> lib
lrwxrwxrwx    1 root     root            11 Aug 19  2019 linuxrc -> bin/busybox
drwxr-xr-x    2 root     root             0 Aug 19  2019 media
drwxr-xr-x    2 root     root             0 Aug 19  2019 mnt
drwxr-xr-x    2 root     root             0 Aug 19  2019 opt
dr-xr-xr-x   66 root     root             0 Jan  1 00:00 proc
drwx------    3 root     root             0 Jan  1 00:01 root
drwxr-xr-x    3 root     root           140 Jan  1 00:00 run
drwxr-xr-x    2 root     root             0 Aug 19  2019 sbin
dr-xr-xr-x   11 root     root             0 Jan  1 00:00 sys
drwxrwxrwt    2 root     root            60 Jan  1 00:00 tmp
drwxr-xr-x    6 root     root             0 Aug 26  2019 usr
drwxr-xr-x    4 root     root             0 Aug 26  2019 var
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.175 MB perf.data (21 samples) ]

# perf record -e cpu-clock --call-graph fp ls -l /
total 4
drwxr-xr-x    2 root     root             0 Aug 26  2019 bin
drwxr-xr-x    5 root     root         12720 Jan  1 00:00 dev
drwxr-xr-x    5 root     root             0 Jan  1 00:00 etc
-rwxr-xr-x    1 root     root           178 Aug 26  2019 init
drwxr-xr-x    2 root     root             0 Aug 26  2019 lib
lrwxrwxrwx    1 root     root             3 Aug 19  2019 lib64 -> lib
lrwxrwxrwx    1 root     root            11 Aug 19  2019 linuxrc -> bin/busybox
drwxr-xr-x    2 root     root             0 Aug 19  2019 media
drwxr-xr-x    2 root     root             0 Aug 19  2019 mnt
drwxr-xr-x    2 root     root             0 Aug 19  2019 opt
dr-xr-xr-x   66 root     root             0 Jan  1 00:00 proc
drwx------    3 root     root             0 Jan  1 00:00 root
drwxr-xr-x    3 root     root           140 Jan  1 00:00 run
drwxr-xr-x    2 root     root             0 Aug 19  2019 sbin
dr-xr-xr-x   11 root     root             0 Jan  1 00:00 sys
drwxrwxrwt    2 root     root            60 Jan  1 00:00 tmp
drwxr-xr-x    6 root     root             0 Aug 26  2019 usr
drwxr-xr-x    4 root     root             0 Aug 26  2019 var
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.004 MB perf.data (19 samples) ]

# perf test
 1: vmlinux symtab matches kallsyms            : Skip
 2: Detect openat syscall event                : FAILED!
 3: Detect openat syscall event on all cpus    : FAILED!
 4: Read samples using the mmap interface      : FAILED!
 5: Test data source output                    : Ok
 6: Parse event definition strings             : FAILED!
 7: Simple expression parser                   : Ok
 8: PERF_RECORD_* events & perf_sample fields  : FAILED!
 9: Parse perf pmu format                      : Ok
10: DSO data read                              : Ok
11: DSO data cache                             : Ok
12: DSO data reopen                            : Ok
13: Roundtrip evsel->name                      : Ok
14: Parse sched tracepoints fields             : Ok
15: syscalls:sys_enter_openat event fields     : FAILED!
16: Setup struct perf_event_attr               : Skip
17: Match and link multiple hists              : Ok
18: 'import perf' in python                    : FAILED!
19: Breakpoint overflow signal handler         : FAILED!
20: Breakpoint overflow sampling               : FAILED!
21: Breakpoint accounting                      : Skip
22: Watchpoint                                 :
22.1: Read Only Watchpoint                     : FAILED!
22.2: Write Only Watchpoint                    : FAILED!
22.3: Read / Write Watchpoint                  : FAILED!
22.4: Modify Watchpoint                        : FAILED!
23: Number of exit events of a simple workload : Ok
24: Software clock events period values        : Ok
25: Object code reading                        : Ok
26: Sample parsing                             : Ok
27: Use a dummy software event to keep tracking: Ok
28: Parse with no sample_id_all bit set        : Ok
29: Filter hist entries                        : Ok
30: Lookup mmap thread                         : Ok
31: Share thread mg                            : Ok
32: Sort output of hist entries                : Ok
33: Cumulate child hist entries                : Ok
34: Track with sched_switch                    : FAILED!
35: Filter fds with revents mask in a fdarray  : Ok
36: Add fd to a fdarray, making it autogrow    : Ok
37: kmod_path__parse                           : Ok
38: Thread map                                 : Ok
39: LLVM search and compile                    :
39.1: Basic BPF llvm compile                    : Skip
39.2: kbuild searching                          : Skip
39.3: Compile source for BPF prologue generation: Skip
39.4: Compile source for BPF relocation         : Skip
40: Session topology                           : FAILED!
41: BPF filter                                 :
41.1: Basic BPF filtering                      : Skip
41.2: BPF pinning                              : Skip
41.3: BPF prologue generation                  : Skip
41.4: BPF relocation checker                   : Skip
42: Synthesize thread map                      : Ok
43: Remove thread map                          : Ok
44: Synthesize cpu map                         : Ok
45: Synthesize stat config                     : Ok
46: Synthesize stat                            : Ok
47: Synthesize stat round                      : Ok
48: Synthesize attr update                     : Ok
49: Event times                                : Ok
50: Read backward ring buffer                  : Skip
51: Print cpu map                              : Ok
52: Probe SDT events                           : Skip
53: is_printable_array                         : Ok
54: Print bitmap                               : Ok
55: perf hooks                                 : Ok
56: builtin clang support                      : Skip (not compiled in)
57: unit_number__scnprintf                     : Ok
58: mem2node                                   : Ok
59: time utils                                 : Ok
60: map_groups__merge_in                       : Ok
#

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH V6 0/3] riscv: Add perf callchain support
  2019-09-04  7:25 ` [PATCH V6 0/3] riscv: Add perf callchain support Greentime Hu
@ 2019-09-04 12:20   ` Guo Ren
  0 siblings, 0 replies; 11+ messages in thread
From: Guo Ren @ 2019-09-04 12:20 UTC (permalink / raw)
  To: Greentime Hu
  Cc: Mao Han, greentime.hu, linux-riscv, Linux Kernel Mailing List,
	linux-csky, Paul Walmsley, Palmer Dabbelt, Christoph Hellwig

Nice job, thank you :)

On Wed, Sep 4, 2019 at 3:26 PM Greentime Hu <green.hu@gmail.com> wrote:
>
> Mao Han <han_mao@c-sky.com> 於 2019年8月29日 週四 下午2:57寫道:
> >
> > This patch set add perf callchain(FP/DWARF) support for RISC-V.
> > It comes from the csky version callchain support with some
> > slight modifications. The patchset base on Linux 5.3-rc6.
> >
> > Changes since v5:
> >   - use walk_stackframe from stacktrace.c to handle
> >     kernel callchain unwinding(fix invalid mem access)
> >
> > Changes since v4:
> >   - Add missing PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
> >     verified with extra CFLAGS(-Wall -Werror)
> >
> > Changes since v3:
> >   - Add more strict check for unwind_frame_kernel
> >   - update for kernel 5.3
> >
> > Changes since v2:
> >   - fix inconsistent comment
> >   - force to build kernel with -fno-omit-frame-pointer if perf
> >     event is enabled
> >
> > Changes since v1:
> >   - simplify implementation and code convention
> >
> > Cc: Paul Walmsley <paul.walmsley@sifive.com>
> > Cc: Greentime Hu <green.hu@gmail.com>
> > Cc: Palmer Dabbelt <palmer@sifive.com>
> > Cc: linux-riscv <linux-riscv@lists.infradead.org>
> > Cc: Christoph Hellwig <hch@lst.de>
> > Cc: Guo Ren <guoren@kernel.org>
> >
> > Mao Han (3):
> >   riscv: Add perf callchain support
> >   riscv: Add support for perf registers sampling
> >   riscv: Add support for libdw
> >
> >  arch/riscv/Kconfig                            |  2 +
> >  arch/riscv/Makefile                           |  3 +
> >  arch/riscv/include/uapi/asm/perf_regs.h       | 42 ++++++++++++
> >  arch/riscv/kernel/Makefile                    |  4 +-
> >  arch/riscv/kernel/perf_callchain.c            | 95 ++++++++++++++++++++++++++
> >  arch/riscv/kernel/perf_regs.c                 | 44 ++++++++++++
> >  arch/riscv/kernel/stacktrace.c                |  2 +-
> >  tools/arch/riscv/include/uapi/asm/perf_regs.h | 42 ++++++++++++
> >  tools/perf/Makefile.config                    |  6 +-
> >  tools/perf/arch/riscv/Build                   |  1 +
> >  tools/perf/arch/riscv/Makefile                |  4 ++
> >  tools/perf/arch/riscv/include/perf_regs.h     | 96 +++++++++++++++++++++++++++
> >  tools/perf/arch/riscv/util/Build              |  2 +
> >  tools/perf/arch/riscv/util/dwarf-regs.c       | 72 ++++++++++++++++++++
> >  tools/perf/arch/riscv/util/unwind-libdw.c     | 57 ++++++++++++++++
> >  15 files changed, 469 insertions(+), 3 deletions(-)
> >  create mode 100644 arch/riscv/include/uapi/asm/perf_regs.h
> >  create mode 100644 arch/riscv/kernel/perf_callchain.c
> >  create mode 100644 arch/riscv/kernel/perf_regs.c
> >  create mode 100644 tools/arch/riscv/include/uapi/asm/perf_regs.h
> >  create mode 100644 tools/perf/arch/riscv/Build
> >  create mode 100644 tools/perf/arch/riscv/Makefile
> >  create mode 100644 tools/perf/arch/riscv/include/perf_regs.h
> >  create mode 100644 tools/perf/arch/riscv/util/Build
> >  create mode 100644 tools/perf/arch/riscv/util/dwarf-regs.c
> >  create mode 100644 tools/perf/arch/riscv/util/unwind-libdw.c
> >
>
> Tested-by: Greentime Hu <greentime.hu@sifive.com>
>
> I tested this patchset based on v5.3-rc6 and it can use dwarf or fp to
> backtrace in Unleashed board.
>
> # perf record -e cpu-clock --call-graph dwarf ls -l /
> total 4
> drwxr-xr-x    2 root     root             0 Aug 26  2019 bin
> drwxr-xr-x    5 root     root         12720 Jan  1 00:00 dev
> drwxr-xr-x    5 root     root             0 Jan  1 00:00 etc
> -rwxr-xr-x    1 root     root           178 Aug 26  2019 init
> drwxr-xr-x    2 root     root             0 Aug 26  2019 lib
> lrwxrwxrwx    1 root     root             3 Aug 19  2019 lib64 -> lib
> lrwxrwxrwx    1 root     root            11 Aug 19  2019 linuxrc -> bin/busybox
> drwxr-xr-x    2 root     root             0 Aug 19  2019 media
> drwxr-xr-x    2 root     root             0 Aug 19  2019 mnt
> drwxr-xr-x    2 root     root             0 Aug 19  2019 opt
> dr-xr-xr-x   66 root     root             0 Jan  1 00:00 proc
> drwx------    3 root     root             0 Jan  1 00:01 root
> drwxr-xr-x    3 root     root           140 Jan  1 00:00 run
> drwxr-xr-x    2 root     root             0 Aug 19  2019 sbin
> dr-xr-xr-x   11 root     root             0 Jan  1 00:00 sys
> drwxrwxrwt    2 root     root            60 Jan  1 00:00 tmp
> drwxr-xr-x    6 root     root             0 Aug 26  2019 usr
> drwxr-xr-x    4 root     root             0 Aug 26  2019 var
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 0.175 MB perf.data (21 samples) ]
>
> # perf record -e cpu-clock --call-graph fp ls -l /
> total 4
> drwxr-xr-x    2 root     root             0 Aug 26  2019 bin
> drwxr-xr-x    5 root     root         12720 Jan  1 00:00 dev
> drwxr-xr-x    5 root     root             0 Jan  1 00:00 etc
> -rwxr-xr-x    1 root     root           178 Aug 26  2019 init
> drwxr-xr-x    2 root     root             0 Aug 26  2019 lib
> lrwxrwxrwx    1 root     root             3 Aug 19  2019 lib64 -> lib
> lrwxrwxrwx    1 root     root            11 Aug 19  2019 linuxrc -> bin/busybox
> drwxr-xr-x    2 root     root             0 Aug 19  2019 media
> drwxr-xr-x    2 root     root             0 Aug 19  2019 mnt
> drwxr-xr-x    2 root     root             0 Aug 19  2019 opt
> dr-xr-xr-x   66 root     root             0 Jan  1 00:00 proc
> drwx------    3 root     root             0 Jan  1 00:00 root
> drwxr-xr-x    3 root     root           140 Jan  1 00:00 run
> drwxr-xr-x    2 root     root             0 Aug 19  2019 sbin
> dr-xr-xr-x   11 root     root             0 Jan  1 00:00 sys
> drwxrwxrwt    2 root     root            60 Jan  1 00:00 tmp
> drwxr-xr-x    6 root     root             0 Aug 26  2019 usr
> drwxr-xr-x    4 root     root             0 Aug 26  2019 var
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 0.004 MB perf.data (19 samples) ]
>
> # perf test
>  1: vmlinux symtab matches kallsyms            : Skip
>  2: Detect openat syscall event                : FAILED!
>  3: Detect openat syscall event on all cpus    : FAILED!
>  4: Read samples using the mmap interface      : FAILED!
>  5: Test data source output                    : Ok
>  6: Parse event definition strings             : FAILED!
>  7: Simple expression parser                   : Ok
>  8: PERF_RECORD_* events & perf_sample fields  : FAILED!
>  9: Parse perf pmu format                      : Ok
> 10: DSO data read                              : Ok
> 11: DSO data cache                             : Ok
> 12: DSO data reopen                            : Ok
> 13: Roundtrip evsel->name                      : Ok
> 14: Parse sched tracepoints fields             : Ok
> 15: syscalls:sys_enter_openat event fields     : FAILED!
> 16: Setup struct perf_event_attr               : Skip
> 17: Match and link multiple hists              : Ok
> 18: 'import perf' in python                    : FAILED!
> 19: Breakpoint overflow signal handler         : FAILED!
> 20: Breakpoint overflow sampling               : FAILED!
> 21: Breakpoint accounting                      : Skip
> 22: Watchpoint                                 :
> 22.1: Read Only Watchpoint                     : FAILED!
> 22.2: Write Only Watchpoint                    : FAILED!
> 22.3: Read / Write Watchpoint                  : FAILED!
> 22.4: Modify Watchpoint                        : FAILED!
> 23: Number of exit events of a simple workload : Ok
> 24: Software clock events period values        : Ok
> 25: Object code reading                        : Ok
> 26: Sample parsing                             : Ok
> 27: Use a dummy software event to keep tracking: Ok
> 28: Parse with no sample_id_all bit set        : Ok
> 29: Filter hist entries                        : Ok
> 30: Lookup mmap thread                         : Ok
> 31: Share thread mg                            : Ok
> 32: Sort output of hist entries                : Ok
> 33: Cumulate child hist entries                : Ok
> 34: Track with sched_switch                    : FAILED!
> 35: Filter fds with revents mask in a fdarray  : Ok
> 36: Add fd to a fdarray, making it autogrow    : Ok
> 37: kmod_path__parse                           : Ok
> 38: Thread map                                 : Ok
> 39: LLVM search and compile                    :
> 39.1: Basic BPF llvm compile                    : Skip
> 39.2: kbuild searching                          : Skip
> 39.3: Compile source for BPF prologue generation: Skip
> 39.4: Compile source for BPF relocation         : Skip
> 40: Session topology                           : FAILED!
> 41: BPF filter                                 :
> 41.1: Basic BPF filtering                      : Skip
> 41.2: BPF pinning                              : Skip
> 41.3: BPF prologue generation                  : Skip
> 41.4: BPF relocation checker                   : Skip
> 42: Synthesize thread map                      : Ok
> 43: Remove thread map                          : Ok
> 44: Synthesize cpu map                         : Ok
> 45: Synthesize stat config                     : Ok
> 46: Synthesize stat                            : Ok
> 47: Synthesize stat round                      : Ok
> 48: Synthesize attr update                     : Ok
> 49: Event times                                : Ok
> 50: Read backward ring buffer                  : Skip
> 51: Print cpu map                              : Ok
> 52: Probe SDT events                           : Skip
> 53: is_printable_array                         : Ok
> 54: Print bitmap                               : Ok
> 55: perf hooks                                 : Ok
> 56: builtin clang support                      : Skip (not compiled in)
> 57: unit_number__scnprintf                     : Ok
> 58: mem2node                                   : Ok
> 59: time utils                                 : Ok
> 60: map_groups__merge_in                       : Ok
> #



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH V6 1/3] riscv: Add perf callchain support
  2019-08-29  6:57 ` [PATCH V6 1/3] " Mao Han
@ 2019-09-04 19:54   ` Paul Walmsley
  2019-09-05  2:30     ` Mao Han
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Walmsley @ 2019-09-04 19:54 UTC (permalink / raw)
  To: Mao Han
  Cc: linux-riscv, linux-kernel, linux-csky, Greentime Hu,
	Palmer Dabbelt, Christoph Hellwig, Guo Ren

Hello Mao Han,

On Thu, 29 Aug 2019, Mao Han wrote:

> This patch add support for perf callchain sampling on riscv platform.
> The return address of leaf function is retrieved from pt_regs as
> it is not saved in the outmost frame.
> 
> Signed-off-by: Mao Han <han_mao@c-sky.com>
> Cc: Paul Walmsley <paul.walmsley@sifive.com>
> Cc: Greentime Hu <green.hu@gmail.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Cc: linux-riscv <linux-riscv@lists.infradead.org>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Guo Ren <guoren@kernel.org>

There are some 'checkpatch.pl --strict' warnings with this patch (below).  
These have been fixed here.  The following patch has been queued for 
v5.4-rc1 with Greentime's Tested-by:.  Thanks for your hard work following 
up on the feedback with these patches -


- Paul


CHECK: Alignment should match open parenthesis
#77: FILE: arch/riscv/kernel/perf_callchain.c:18:
+static unsigned long user_backtrace(struct perf_callchain_entry_ctx 
*entry,
+			unsigned long fp, unsigned long reg_ra)

CHECK: Blank lines aren't necessary after an open brace '{'
#146: FILE: arch/riscv/kernel/perf_callchain.c:87:
+{
+

CHECK: Alignment should match open parenthesis
#165: FILE: arch/riscv/kernel/stacktrace.c:23:
+void notrace walk_stackframe(struct task_struct *task,
 	struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg)

------

From: Mao Han <han_mao@c-sky.com>
Date: Thu, 29 Aug 2019 14:57:00 +0800
Subject: [PATCH] riscv: Add perf callchain support

This patch adds support for perf callchain sampling on riscv platforms.
The return address of leaf function is retrieved from pt_regs as
it is not saved in the outmost frame.

Signed-off-by: Mao Han <han_mao@c-sky.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: linux-riscv <linux-riscv@lists.infradead.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Guo Ren <guoren@kernel.org>
Tested-by: Greentime Hu <greentime.hu@sifive.com>
[paul.walmsley@sifive.com: fixed some 'checkpatch.pl --strict' issues;
 fixed patch description spelling]
Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
---
 arch/riscv/Makefile                |  3 +
 arch/riscv/kernel/Makefile         |  3 +-
 arch/riscv/kernel/perf_callchain.c | 94 ++++++++++++++++++++++++++++++
 arch/riscv/kernel/stacktrace.c     |  4 +-
 4 files changed, 101 insertions(+), 3 deletions(-)
 create mode 100644 arch/riscv/kernel/perf_callchain.c

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index a73659e30f8d..4f0a3d2018d2 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -54,6 +54,9 @@ endif
 ifeq ($(CONFIG_MODULE_SECTIONS),y)
 	KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/riscv/kernel/module.lds
 endif
+ifeq ($(CONFIG_PERF_EVENTS),y)
+        KBUILD_CFLAGS += -fno-omit-frame-pointer
+endif
 
 KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
 
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 2420d37d96de..b1bea89fc814 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_MODULE_SECTIONS)	+= module-sections.o
 obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= mcount-dyn.o
 
-obj-$(CONFIG_PERF_EVENTS)      += perf_event.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_event.o
+obj-$(CONFIG_PERF_EVENTS)	+= perf_callchain.o
 
 clean:
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
new file mode 100644
index 000000000000..8d2804f05cf9
--- /dev/null
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#include <linux/perf_event.h>
+#include <linux/uaccess.h>
+
+/* Kernel callchain */
+struct stackframe {
+	unsigned long fp;
+	unsigned long ra;
+};
+
+/*
+ * Get the return address for a single stackframe and return a pointer to the
+ * next frame tail.
+ */
+static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
+				    unsigned long fp, unsigned long reg_ra)
+{
+	struct stackframe buftail;
+	unsigned long ra = 0;
+	unsigned long *user_frame_tail =
+			(unsigned long *)(fp - sizeof(struct stackframe));
+
+	/* Check accessibility of one struct frame_tail beyond */
+	if (!access_ok(user_frame_tail, sizeof(buftail)))
+		return 0;
+	if (__copy_from_user_inatomic(&buftail, user_frame_tail,
+				      sizeof(buftail)))
+		return 0;
+
+	if (reg_ra != 0)
+		ra = reg_ra;
+	else
+		ra = buftail.ra;
+
+	fp = buftail.fp;
+	if (ra != 0)
+		perf_callchain_store(entry, ra);
+	else
+		return 0;
+
+	return fp;
+}
+
+/*
+ * This will be called when the target is in user mode
+ * This function will only be called when we use
+ * "PERF_SAMPLE_CALLCHAIN" in
+ * kernel/events/core.c:perf_prepare_sample()
+ *
+ * How to trigger perf_callchain_[user/kernel] :
+ * $ perf record -e cpu-clock --call-graph fp ./program
+ * $ perf report --call-graph
+ *
+ * On RISC-V platform, the program being sampled and the C library
+ * need to be compiled with -fno-omit-frame-pointer, otherwise
+ * the user stack will not contain function frame.
+ */
+void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
+			 struct pt_regs *regs)
+{
+	unsigned long fp = 0;
+
+	/* RISC-V does not support perf in guest mode. */
+	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+		return;
+
+	fp = regs->s0;
+	perf_callchain_store(entry, regs->sepc);
+
+	fp = user_backtrace(entry, fp, regs->ra);
+	while (fp && !(fp & 0x3) && entry->nr < entry->max_stack)
+		fp = user_backtrace(entry, fp, 0);
+}
+
+bool fill_callchain(unsigned long pc, void *entry)
+{
+	return perf_callchain_store(entry, pc);
+}
+
+void notrace walk_stackframe(struct task_struct *task,
+	struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg);
+void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
+			   struct pt_regs *regs)
+{
+	/* RISC-V does not support perf in guest mode. */
+	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+		pr_warn("RISC-V does not support perf in guest mode!");
+		return;
+	}
+
+	walk_stackframe(NULL, regs, fill_callchain, entry);
+}
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
index f15642715d1a..0940681d2f68 100644
--- a/arch/riscv/kernel/stacktrace.c
+++ b/arch/riscv/kernel/stacktrace.c
@@ -19,8 +19,8 @@ struct stackframe {
 	unsigned long ra;
 };
 
-static void notrace walk_stackframe(struct task_struct *task,
-	struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg)
+void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
+			     bool (*fn)(unsigned long, void *), void *arg)
 {
 	unsigned long fp, sp, pc;
 
-- 
2.23.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH V6 2/3] riscv: Add support for perf registers sampling
  2019-08-29  6:57 ` [PATCH V6 2/3] riscv: Add support for perf registers sampling Mao Han
@ 2019-09-04 21:22   ` Paul Walmsley
  0 siblings, 0 replies; 11+ messages in thread
From: Paul Walmsley @ 2019-09-04 21:22 UTC (permalink / raw)
  To: Mao Han
  Cc: linux-riscv, linux-kernel, linux-csky, Greentime Hu,
	Palmer Dabbelt, Christoph Hellwig, Guo Ren

Hello Mao Han,

On Thu, 29 Aug 2019, Mao Han wrote:

> This patch implements the perf registers sampling and validation API
> for riscv arch. The valid registers and their register ID are defined in
> perf_regs.h. Perf tool can backtrace in userspace with unwind library
> and the registers/user stack dump support.

[ ... ]

> diff --git a/arch/riscv/include/uapi/asm/perf_regs.h b/arch/riscv/include/uapi/asm/perf_regs.h
> new file mode 100644
> index 0000000..df1a581
> --- /dev/null
> +++ b/arch/riscv/include/uapi/asm/perf_regs.h
> @@ -0,0 +1,42 @@
> +/* SPDX-License-Identifier: GPL-2.0 */

All of the other Linux architectures use "GPL-2.0 WITH Linux-syscall-note" 
for their license for the perf uapi files.  Could you please change this 
license string to match the standard Linux practice?  Then I think it 
should be good to merge.


- Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH V6 3/3] riscv: Add support for libdw
  2019-08-29  6:57 ` [PATCH V6 3/3] riscv: Add support for libdw Mao Han
@ 2019-09-04 21:24   ` Paul Walmsley
  2019-09-05  2:49     ` Mao Han
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Walmsley @ 2019-09-04 21:24 UTC (permalink / raw)
  To: Mao Han
  Cc: linux-riscv, linux-kernel, linux-csky, Greentime Hu,
	Palmer Dabbelt, Christoph Hellwig, Guo Ren

Hello Mao Han,

On Thu, 29 Aug 2019, Mao Han wrote:

> This patch add support for DWARF register mappings and libdw registers
> initialization, which is used by perf callchain analyzing when
> --call-graph=dwarf is given.

> diff --git a/tools/arch/riscv/include/uapi/asm/perf_regs.h b/tools/arch/riscv/include/uapi/asm/perf_regs.h
> new file mode 100644
> index 0000000..df1a581
> --- /dev/null
> +++ b/tools/arch/riscv/include/uapi/asm/perf_regs.h
> @@ -0,0 +1,42 @@
> +/* SPDX-License-Identifier: GPL-2.0 */

As with 

https://lore.kernel.org/linux-riscv/CAJF2gTRXH_bx0rwsTZMTnX+umZfVTL_iVnewPtVM50sLaqJPTg@mail.gmail.com/T/#t

is it possible to change this license string to "GPL-2.0 WITH 
Linux-syscall-note" to match the other Linux architectures? 


- Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH V6 1/3] riscv: Add perf callchain support
  2019-09-04 19:54   ` Paul Walmsley
@ 2019-09-05  2:30     ` Mao Han
  0 siblings, 0 replies; 11+ messages in thread
From: Mao Han @ 2019-09-05  2:30 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-riscv, linux-kernel, linux-csky

On Wed, Sep 04, 2019 at 12:54:41PM -0700, Paul Walmsley wrote:
> Hello Mao Han,
> 
> On Thu, 29 Aug 2019, Mao Han wrote:
> 
> > This patch add support for perf callchain sampling on riscv platform.
> > The return address of leaf function is retrieved from pt_regs as
> > it is not saved in the outmost frame.
> > 
> > Signed-off-by: Mao Han <han_mao@c-sky.com>
> > Cc: Paul Walmsley <paul.walmsley@sifive.com>
> > Cc: Greentime Hu <green.hu@gmail.com>
> > Cc: Palmer Dabbelt <palmer@sifive.com>
> > Cc: linux-riscv <linux-riscv@lists.infradead.org>
> > Cc: Christoph Hellwig <hch@lst.de>
> > Cc: Guo Ren <guoren@kernel.org>
> 
> There are some 'checkpatch.pl --strict' warnings with this patch (below).  
> These have been fixed here.  The following patch has been queued for 
> v5.4-rc1 with Greentime's Tested-by:.  Thanks for your hard work following 
> up on the feedback with these patches -
Thanks for the fixes. I'll check patches with --strict next time.

Thanks,
Mao Han

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH V6 3/3] riscv: Add support for libdw
  2019-09-04 21:24   ` Paul Walmsley
@ 2019-09-05  2:49     ` Mao Han
  0 siblings, 0 replies; 11+ messages in thread
From: Mao Han @ 2019-09-05  2:49 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-riscv, linux-kernel, linux-csky

On Wed, Sep 04, 2019 at 02:24:57PM -0700, Paul Walmsley wrote:
> Hello Mao Han,
> 
> On Thu, 29 Aug 2019, Mao Han wrote:
> 
> > This patch add support for DWARF register mappings and libdw registers
> > initialization, which is used by perf callchain analyzing when
> > --call-graph=dwarf is given.
> 
> > diff --git a/tools/arch/riscv/include/uapi/asm/perf_regs.h b/tools/arch/riscv/include/uapi/asm/perf_regs.h
> > new file mode 100644
> > index 0000000..df1a581
> > --- /dev/null
> > +++ b/tools/arch/riscv/include/uapi/asm/perf_regs.h
> > @@ -0,0 +1,42 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> 
> As with 
> 
> https://lore.kernel.org/linux-riscv/CAJF2gTRXH_bx0rwsTZMTnX+umZfVTL_iVnewPtVM50sLaqJPTg@mail.gmail.com/T/#t
> 
> is it possible to change this license string to "GPL-2.0 WITH 
> Linux-syscall-note" to match the other Linux architectures? 
>
Thanks for suggestion. I didn't notice the UAPI headers are supposed to 
have the exception notes. I'll update the license string and resend them.

Thanks,
Mao Han

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, back to index

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-29  6:56 [PATCH V6 0/3] riscv: Add perf callchain support Mao Han
2019-08-29  6:57 ` [PATCH V6 1/3] " Mao Han
2019-09-04 19:54   ` Paul Walmsley
2019-09-05  2:30     ` Mao Han
2019-08-29  6:57 ` [PATCH V6 2/3] riscv: Add support for perf registers sampling Mao Han
2019-09-04 21:22   ` Paul Walmsley
2019-08-29  6:57 ` [PATCH V6 3/3] riscv: Add support for libdw Mao Han
2019-09-04 21:24   ` Paul Walmsley
2019-09-05  2:49     ` Mao Han
2019-09-04  7:25 ` [PATCH V6 0/3] riscv: Add perf callchain support Greentime Hu
2019-09-04 12:20   ` Guo Ren

Linux-csky Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-csky/0 linux-csky/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-csky linux-csky/ https://lore.kernel.org/linux-csky \
		linux-csky@vger.kernel.org
	public-inbox-index linux-csky

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-csky


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git