linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 00/15] perf bpf: Probing with local variable
@ 2015-05-24  8:27 He Kuang
  2015-05-24  8:27 ` [RFC PATCH v2 01/15] perf tools: Add lib/bpf to cscope target list He Kuang
                   ` (14 more replies)
  0 siblings, 15 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:27 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

This is the 2nd version of perf bpf: Probing with local variable,
original discusions: https://lkml.org/lkml/2015/5/5/260.

Patches based on https://lkml.org/lkml/2015/5/17/84 (perf tools:
introduce 'perf bpf' command to load eBPF programs).

v1-v2:

  - Copy bpf byte-code related headers to tools/lib/bpf.
  
  - Combine pt_regs offset to arch_regs_table, and add
    calling_regs_table.
    
  - Support $params without debuginfo and use the same keyword for
    generating bpf prologue without debuginfo.
    
  - Save bpf prologue intermediate result to stack, so we can use the
    4 regs(R2,R3,R4,R5) for variable passing according to bpf calling
    convention.
    
  - Move bpf prologue code to tools/lib/bpf.
  
  - Sample codes in patch instead of comments.
  
  - Fix code style problems mentioned by Alexei and Masami.

Thanks.

He Kuang (15):
  perf tools: Add lib/bpf to cscope target list
  perf bpf: Support custom vmlinux path
  perf bpf: Save pt_regs info from debuginfo
  perf tools: Add functions to get calling regs
  perf tools: Add pt_regs offsets and calling regs for x86
  bpf tools: Add headers for generating bpf bytecode
  bpf tools: Convert arglist to bpf prologue
  bpf tools: Fetch calling regs to bpf arglist
  perf probe: Support $params without debuginfo
  perf bpf: Process debuginfo for generating bpf prologue
  perf bpf: Synthesize vars to generate bpf prologue
  perf bpf: Generate bpf prologue without debuginfo
  perf bpf: Combine bpf prologue and bpf prog
  samples/bpf: Add sample for testing bpf fetch args
  samples/bpf: Add sample for no-debuginfo case

 samples/bpf/Makefile                              |   2 +
 samples/bpf/sample_bpf_fetch_args.c               |  62 +++++++
 samples/bpf/sample_bpf_fetch_args_without_debug.c |  49 ++++++
 tools/lib/bpf/Build                               |   2 +-
 tools/lib/bpf/bpf.h                               | 187 +++++++++++++++++++++
 tools/lib/bpf/gen_prologue.c                      | 127 ++++++++++++++
 tools/lib/bpf/libbpf.c                            |  27 +++
 tools/lib/bpf/libbpf.h                            |  14 ++
 tools/perf/Makefile.perf                          |   2 +-
 tools/perf/arch/x86/util/dwarf-regs.c             | 100 ++++++++---
 tools/perf/builtin-bpf.c                          |   3 +
 tools/perf/util/bpf-loader.c                      |  27 +++
 tools/perf/util/include/dwarf-regs.h              |  15 ++
 tools/perf/util/probe-event.c                     | 121 ++++++++++++++
 tools/perf/util/probe-event.h                     |   3 +
 tools/perf/util/probe-finder.c                    | 193 ++++++++++++++++++++++
 tools/perf/util/probe-finder.h                    |   4 +
 17 files changed, 915 insertions(+), 23 deletions(-)
 create mode 100644 samples/bpf/sample_bpf_fetch_args.c
 create mode 100644 samples/bpf/sample_bpf_fetch_args_without_debug.c
 create mode 100644 tools/lib/bpf/gen_prologue.c

--
1.8.5.2


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

* [RFC PATCH v2 01/15] perf tools: Add lib/bpf to cscope target list
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
@ 2015-05-24  8:27 ` He Kuang
  2015-05-24  8:27 ` [RFC PATCH v2 02/15] perf bpf: Support custom vmlinux path He Kuang
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:27 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Add lib/bpf folder to cscope list.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/Makefile.perf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c69821c..7b77d14 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -444,7 +444,7 @@ INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
 $(DOC_TARGETS):
 	$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
 
-TAG_FOLDERS= . ../lib/traceevent ../lib/api ../lib/symbol
+TAG_FOLDERS= . ../lib/traceevent ../lib/api ../lib/symbol ../lib/bpf
 TAG_FILES= ../../include/uapi/linux/perf_event.h
 
 TAGS:
-- 
1.8.5.2


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

* [RFC PATCH v2 02/15] perf bpf: Support custom vmlinux path
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
  2015-05-24  8:27 ` [RFC PATCH v2 01/15] perf tools: Add lib/bpf to cscope target list He Kuang
@ 2015-05-24  8:27 ` He Kuang
  2015-05-24  8:27 ` [RFC PATCH v2 03/15] perf bpf: Save pt_regs info from debuginfo He Kuang
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:27 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Make bpf command support -k option, when inserting probe point which
needs debuginfo, a customized vmlinux path can be specified.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/builtin-bpf.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/builtin-bpf.c b/tools/perf/builtin-bpf.c
index 4ef294a..9ea34b3 100644
--- a/tools/perf/builtin-bpf.c
+++ b/tools/perf/builtin-bpf.c
@@ -11,6 +11,7 @@
 #include "builtin.h"
 #include "perf.h"
 #include "debug.h"
+#include "util/symbol.h"
 #include "parse-options.h"
 #include "bpf-loader.h"
 
@@ -30,6 +31,8 @@ static struct bpf_cmd bpf_cmds[];
 struct option bpf_options[] = {
 	OPT_INCR('v', "verbose", &verbose, "be more verbose "
 					   "(show debug information)"),
+	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+		   "file", "vmlinux pathname"),
 	OPT_END()
 };
 
-- 
1.8.5.2


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

* [RFC PATCH v2 03/15] perf bpf: Save pt_regs info from debuginfo
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
  2015-05-24  8:27 ` [RFC PATCH v2 01/15] perf tools: Add lib/bpf to cscope target list He Kuang
  2015-05-24  8:27 ` [RFC PATCH v2 02/15] perf bpf: Support custom vmlinux path He Kuang
@ 2015-05-24  8:27 ` He Kuang
  2015-05-24 13:31   ` Masami Hiramatsu
  2015-05-24  8:28 ` [RFC PATCH v2 04/15] perf tools: Add functions to get calling regs He Kuang
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:27 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Save reg number in function convert_variable_location() instead of the
register string name, so we can fetch the target register from bpf
context register later.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/include/dwarf-regs.h | 13 +++++++++++++
 tools/perf/util/probe-event.h        |  1 +
 tools/perf/util/probe-finder.c       | 11 +++++++++++
 3 files changed, 25 insertions(+)

diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 8f14965..566ff6d 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -2,7 +2,20 @@
 #define _PERF_DWARF_REGS_H_
 
 #ifdef HAVE_DWARF_SUPPORT
+struct arch_regs_info {
+	const char      *name;  /* Architecture dependent register string */
+	int             offset; /* Reg offset in struct pt_regs */
+	int             size;   /* Reg size */
+};
+
+#define ARCH_REGS_INFO(r, pt_reg_name)					\
+	{.name	= r,							\
+	.offset = offsetof(struct pt_regs, pt_reg_name),		\
+	.size   = sizeof(((struct pt_regs *)0)->pt_reg_name)}		\
+
 const char *get_arch_regstr(unsigned int n);
+int get_arch_reg_offset(unsigned int n);
+int get_arch_reg_size(unsigned int n);
 #endif
 
 #endif
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index d6b7834..6c19395 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -29,6 +29,7 @@ struct probe_trace_arg {
 	char				*value;	/* Base value */
 	char				*type;	/* Type name */
 	struct probe_trace_arg_ref	*ref;	/* Referencing offset */
+	unsigned int                    regn;   /* Regn from dwarf */
 };
 
 /* kprobe-tracer and uprobe-tracer tracing event (point + arg) */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index ee27b74..681af00 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -159,6 +159,16 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
 	return ref;
 }
 
+int __attribute__ ((weak))
+get_arch_reg_offset(unsigned int n __maybe_unused) {
+	return -1;
+}
+
+int __attribute__ ((weak))
+get_arch_reg_size(unsigned int n __maybe_unused) {
+	return -1;
+}
+
 /*
  * Convert a location into trace_arg.
  * If tvar == NULL, this just checks variable can be converted.
@@ -260,6 +270,7 @@ static_var:
 		return -ERANGE;
 	}
 
+	tvar->regn = regn;
 	tvar->value = strdup(regs);
 	if (tvar->value == NULL)
 		return -ENOMEM;
-- 
1.8.5.2


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

* [RFC PATCH v2 04/15] perf tools: Add functions to get calling regs
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (2 preceding siblings ...)
  2015-05-24  8:27 ` [RFC PATCH v2 03/15] perf bpf: Save pt_regs info from debuginfo He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 05/15] perf tools: Add pt_regs offsets and calling regs for x86 He Kuang
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

For generating function formal parameters without debuginfo, add
function to get names and offsets of architecture dependent calling
regs.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/include/dwarf-regs.h |  2 ++
 tools/perf/util/probe-finder.c       | 10 ++++++++++
 2 files changed, 12 insertions(+)

diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 566ff6d..dc02243 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -16,6 +16,8 @@ struct arch_regs_info {
 const char *get_arch_regstr(unsigned int n);
 int get_arch_reg_offset(unsigned int n);
 int get_arch_reg_size(unsigned int n);
+const char *get_arch_calling_reg_str(unsigned int n);
+int get_arch_calling_reg_offset(unsigned int n);
 #endif
 
 #endif
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 681af00..4de7649 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -169,6 +169,16 @@ get_arch_reg_size(unsigned int n __maybe_unused) {
 	return -1;
 }
 
+const char __attribute__ ((weak))
+*get_arch_calling_reg_str(unsigned int n __maybe_unused) {
+	return NULL;
+}
+
+int __attribute__ ((weak))
+get_arch_calling_reg_offset(unsigned int n __maybe_unused) {
+	return -1;
+}
+
 /*
  * Convert a location into trace_arg.
  * If tvar == NULL, this just checks variable can be converted.
-- 
1.8.5.2


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

* [RFC PATCH v2 05/15] perf tools: Add pt_regs offsets and calling regs for x86
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (3 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 04/15] perf tools: Add functions to get calling regs He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 06/15] bpf tools: Add headers for generating bpf bytecode He Kuang
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Combine pt_regs offset of each registers into arch_regs_table. And add
architecture dependent calling_regs_table.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/arch/x86/util/dwarf-regs.c | 100 +++++++++++++++++++++++++++-------
 1 file changed, 79 insertions(+), 21 deletions(-)

diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
index be22dd4..c7f2309 100644
--- a/tools/perf/arch/x86/util/dwarf-regs.c
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
@@ -22,54 +22,112 @@
 
 #include <stddef.h>
 #include <dwarf-regs.h>
+#include <string.h>
+#include <linux/ptrace.h>
 
 /*
  * Generic dwarf analysis helpers
  */
 
+#ifndef __x86_64__
 #define X86_32_MAX_REGS 8
-const char *x86_32_regs_table[X86_32_MAX_REGS] = {
-	"%ax",
+const struct arch_regs_info x86_32_regs_table[X86_32_MAX_REGS] = {
+	ARCH_REGS_INFO("%ax",		eax),
+	ARCH_REGS_INFO("%cx",		ecx),
+	ARCH_REGS_INFO("%dx",		edx),
+	ARCH_REGS_INFO("%bx",		ebx),
+	ARCH_REGS_INFO("$stack",	esp), /* Stack address instead of %sp */
+	ARCH_REGS_INFO("%bp",		ebp),
+	ARCH_REGS_INFO("%si",		esi),
+	ARCH_REGS_INFO("%di",		edi),
+};
+
+#define X86_32_MAX_CALLING_REGS	(2)
+const char *x86_32_calling_regs_table[] = {
 	"%cx",
 	"%dx",
-	"%bx",
-	"$stack",	/* Stack address instead of %sp */
-	"%bp",
-	"%si",
-	"%di",
 };
 
+#else
 #define X86_64_MAX_REGS 16
-const char *x86_64_regs_table[X86_64_MAX_REGS] = {
-	"%ax",
+const struct arch_regs_info x86_64_regs_table[X86_64_MAX_REGS] = {
+	ARCH_REGS_INFO("%ax",		rax),
+	ARCH_REGS_INFO("%dx",		rdx),
+	ARCH_REGS_INFO("%cx",		rcx),
+	ARCH_REGS_INFO("%bx",		rbx),
+	ARCH_REGS_INFO("%si",		rsi),
+	ARCH_REGS_INFO("%di",		rdi),
+	ARCH_REGS_INFO("%bp",		rbp),
+	ARCH_REGS_INFO("%sp",		rsp),
+	ARCH_REGS_INFO("%r8",		r8),
+	ARCH_REGS_INFO("%r9",		r9),
+	ARCH_REGS_INFO("%r10",		r10),
+	ARCH_REGS_INFO("%r11",		r11),
+	ARCH_REGS_INFO("%r12",		r12),
+	ARCH_REGS_INFO("%r13",		r13),
+	ARCH_REGS_INFO("%r14",		r14),
+	ARCH_REGS_INFO("%r15",		r15),
+};
+
+#define X86_64_MAX_CALLING_REGS	(6)
+const char *x86_64_calling_regs_table[] = {
+	"%di",
+	"%si",
 	"%dx",
 	"%cx",
-	"%bx",
-	"%si",
-	"%di",
-	"%bp",
-	"%sp",
 	"%r8",
 	"%r9",
-	"%r10",
-	"%r11",
-	"%r12",
-	"%r13",
-	"%r14",
-	"%r15",
 };
 
+#endif
+
 /* TODO: switching by dwarf address size */
 #ifdef __x86_64__
 #define ARCH_MAX_REGS X86_64_MAX_REGS
 #define arch_regs_table x86_64_regs_table
+#define ARCH_MAX_CALLING_REGS X86_64_MAX_CALLING_REGS
+#define arch_calling_regs_table x86_64_calling_regs_table
 #else
 #define ARCH_MAX_REGS X86_32_MAX_REGS
 #define arch_regs_table x86_32_regs_table
+#define ARCH_MAX_CALLING_REGS X86_32_MAX_CALLING_REGS
+#define arch_calling_regs_table x86_32_calling_regs_table
 #endif
 
 /* Return architecture dependent register string (for kprobe-tracer) */
 const char *get_arch_regstr(unsigned int n)
 {
-	return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
+	return (n < ARCH_MAX_REGS) ? arch_regs_table[n].name : NULL;
+}
+
+int get_arch_reg_offset(unsigned int n)
+{
+	return (n < ARCH_MAX_REGS) ? arch_regs_table[n].offset : -1;
+}
+
+int get_arch_reg_size(unsigned int n)
+{
+	return (n < ARCH_MAX_REGS) ? arch_regs_table[n].size : -1;
+}
+
+const char *get_arch_calling_reg_str(unsigned int n)
+{
+	return (n < ARCH_MAX_CALLING_REGS) ?
+		arch_calling_regs_table[n] : NULL;
+}
+
+int get_arch_calling_reg_offset(unsigned int n)
+{
+	int i;
+
+	if (n >= ARCH_MAX_CALLING_REGS)
+		return -1;
+
+	for (i = 0; i < ARCH_MAX_REGS; i++) {
+		if (!strcmp(arch_calling_regs_table[n],
+				arch_regs_table[i].name))
+			return arch_regs_table[i].offset;
+	}
+
+	return -1;
 }
-- 
1.8.5.2


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

* [RFC PATCH v2 06/15] bpf tools: Add headers for generating bpf bytecode
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (4 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 05/15] perf tools: Add pt_regs offsets and calling regs for x86 He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 07/15] bpf tools: Convert arglist to bpf prologue He Kuang
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Copying bpf instruction macros from sample/bpf/libbpf.h, and register
alias from include/linux/ftrace.h, so we can generating bpf bytecode by
using these macros.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/lib/bpf/bpf.h | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 187 insertions(+)

diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index fb2a613..7e3e83a 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -21,4 +21,191 @@ int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns,
 		     u32 kern_version, char *log_buf,
 		     size_t log_buf_sz);
 
+/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
+
+#define BPF_ALU64_REG(OP, DST, SRC)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+#define BPF_ALU32_REG(OP, DST, SRC)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_OP(OP) | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
+
+#define BPF_ALU64_IMM(OP, DST, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,	\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+#define BPF_ALU32_IMM(OP, DST, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_OP(OP) | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Short form of mov, dst_reg = src_reg */
+
+#define BPF_MOV64_REG(DST, SRC)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_MOV | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+/* Short form of mov, dst_reg = imm32 */
+
+#define BPF_MOV64_IMM(DST, IMM)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_MOV | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */
+#define BPF_LD_IMM64(DST, IMM)					\
+	BPF_LD_IMM64_RAW(DST, 0, IMM)
+
+#define BPF_LD_IMM64_RAW(DST, SRC, IMM)				\
+	(((struct bpf_insn) {					\
+		.code  = BPF_LD | BPF_DW | BPF_IMM,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = (__u32) (IMM) }),			\
+	((struct bpf_insn) {					\
+		.code  = 0, /* zero is reserved opcode */	\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = ((__u64) (IMM)) >> 32 }))
+
+#ifndef BPF_PSEUDO_MAP_FD
+# define BPF_PSEUDO_MAP_FD	1
+#endif
+
+/* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
+#define BPF_LD_MAP_FD(DST, MAP_FD)				\
+	BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
+
+
+/* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
+
+#define BPF_LD_ABS(SIZE, IMM)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS,	\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Memory load, dst_reg = *(uint *) (src_reg + off16) */
+
+#define BPF_LDX_MEM(SIZE, DST, SRC, OFF)			\
+	((struct bpf_insn) {					\
+		.code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Memory store, *(uint *) (dst_reg + off16) = src_reg */
+
+#define BPF_STX_MEM(SIZE, DST, SRC, OFF)			\
+	((struct bpf_insn) {					\
+		.code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Memory store, *(uint *) (dst_reg + off16) = imm32 */
+
+#define BPF_ST_MEM(SIZE, DST, OFF, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Conditional jumps against registers,
+   if (dst_reg 'op' src_reg) goto pc + off16 */
+
+#define BPF_JMP_REG(OP, DST, SRC, OFF)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_OP(OP) | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Conditional jumps against immediates,
+   if (dst_reg 'op' imm32) goto pc + off16 */
+
+#define BPF_JMP_IMM(OP, DST, IMM, OFF)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_OP(OP) | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Raw code statement block */
+
+#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)			\
+	((struct bpf_insn) {					\
+		.code  = CODE,					\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Program exit */
+
+#define BPF_EXIT_INSN()						\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_EXIT,			\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+/* Function call */
+
+#define BPF_EMIT_CALL(FUNC)				       \
+	((struct bpf_insn) {				       \
+	       .code  = BPF_JMP | BPF_CALL,		       \
+	       .dst_reg = 0,				       \
+	       .src_reg = 0,				       \
+	       .off   = 0,				       \
+	       .imm   = FUNC })
+
+/* ArgX, context and stack frame pointer register positions. Note,
+ * Arg1, Arg2, Arg3, etc are used as argument mappings of function
+ * calls in BPF_CALL instruction.
+ */
+#define BPF_REG_ARG1	BPF_REG_1
+#define BPF_REG_ARG2	BPF_REG_2
+#define BPF_REG_ARG3	BPF_REG_3
+#define BPF_REG_ARG4	BPF_REG_4
+#define BPF_REG_ARG5	BPF_REG_5
+#define BPF_REG_CTX	BPF_REG_6
+#define BPF_REG_FP	BPF_REG_10
+
 #endif
-- 
1.8.5.2


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

* [RFC PATCH v2 07/15] bpf tools: Convert arglist to bpf prologue
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (5 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 06/15] bpf tools: Add headers for generating bpf bytecode He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 08/15] bpf tools: Fetch calling regs to bpf arglist He Kuang
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

When all arguments in bpf config section are collected in register and
offset form, this patch will fetch them from bpf context register and
place them as bpf input parameters.

By bpf calling convention, we restrict the max fetched arg number to 4.

Bpf prologue is generated as the following steps:
1. alloc dst address in stack -> r1
2. set size -> r2
3. fetch base register and offset -> r3
4. call BPF_FUNC_probe_read
5. loop 1
6. save intermediate result and process next arg
7. restore intermediate result to arg2~5

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/lib/bpf/Build          |   2 +-
 tools/lib/bpf/gen_prologue.c | 108 +++++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h       |  10 ++++
 3 files changed, 119 insertions(+), 1 deletion(-)
 create mode 100644 tools/lib/bpf/gen_prologue.c

diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build
index d874975..c910805 100644
--- a/tools/lib/bpf/Build
+++ b/tools/lib/bpf/Build
@@ -1 +1 @@
-libbpf-y := libbpf.o bpf.o
+libbpf-y := libbpf.o bpf.o gen_prologue.o
diff --git a/tools/lib/bpf/gen_prologue.c b/tools/lib/bpf/gen_prologue.c
new file mode 100644
index 0000000..ca8aa1c
--- /dev/null
+++ b/tools/lib/bpf/gen_prologue.c
@@ -0,0 +1,108 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <dwarf-regs.h>
+#include <debug.h>
+
+#include "libbpf.h"
+#include "bpf.h"
+
+#define BPF_REG_SIZE		(8)
+
+unsigned int bpf_prologue_arg_deref(int offset, int stack_index, int depth,
+			char *new_prog,	bool last)
+{
+	struct bpf_insn tmp_insns[6] = {};
+	struct bpf_insn *insn = tmp_insns;
+	unsigned int size;
+
+	if (!depth) {
+		/* base register */
+		if (offset < 0)
+			return 0;
+
+		/* load ctx to r3 */
+		*insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_CTX, offset);
+
+		if (!last) {
+			/* r7 for stack space */
+			*insn++ = BPF_MOV64_REG(BPF_REG_7, BPF_REG_FP);
+			*insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_7,
+						-BPF_REG_SIZE * stack_index);
+			/* clear stack */
+			*insn++ = BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_8,
+					-BPF_REG_SIZE * stack_index);
+		} else {
+			/* store r3 to stack */
+			*insn++ = BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_3,
+					-BPF_REG_SIZE * stack_index);
+		}
+	} else {
+		/* refs */
+		/* r3 += offset */
+		*insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, offset);
+
+		/* r2 = size */
+		*insn++ = BPF_ALU64_IMM(BPF_MOV, BPF_REG_2, 0x0008);
+
+		/* r1 = r7 */
+		*insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_7);
+
+		/* call BPF_FUNC_probe_read
+		 *  r1: ptr to stack
+		 *  r2: stack size
+		 *  r3: unsafe ptr
+		 */
+		*insn++ = BPF_EMIT_CALL(BPF_FUNC_probe_read);
+
+		if (!last)
+			/* fetch stack intermediate to r3 */
+			*insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_FP,
+					-BPF_REG_SIZE * stack_index);
+	}
+
+	size = sizeof(*insn) * (insn - tmp_insns);
+	if (new_prog)
+		memcpy(new_prog, tmp_insns, size);
+
+	return size;
+}
+
+unsigned int bpf_prologue_begin(char *new_prog)
+{
+	struct bpf_insn *new_insn;
+
+	new_insn = (struct bpf_insn *)new_prog;
+
+	if (new_insn) {
+		/* save arg1 to ctx */
+		*new_insn++ = BPF_MOV64_REG(BPF_REG_CTX, BPF_REG_ARG1);
+		/* set r8 to 0 */
+		*new_insn++ = BPF_ALU64_IMM(BPF_MOV, BPF_REG_8, 0);
+	} else
+		new_insn += 2;
+
+	return (char *)new_insn - new_prog;
+}
+
+unsigned int bpf_prologue_end(char *new_prog, int nargs)
+{
+	struct bpf_insn *new_insn;
+	int i;
+
+	new_insn = (struct bpf_insn *)new_prog;
+
+	nargs = min(BPF_PROLOGUE_NRARGS_MAX, nargs);
+	for (i = 0; i < nargs; i++) {
+		/* result in stack, move to r2~r5 */
+		if (new_prog)
+			*new_insn = BPF_LDX_MEM(BPF_DW,
+						BPF_REG_ARG2 + i,
+						BPF_REG_FP,
+						-BPF_REG_SIZE * (i + 1));
+		new_insn++;
+	}
+
+	return (char *)new_insn - new_prog;
+}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 31ff5d9..cf22a6a 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -63,4 +63,14 @@ struct bpf_map_def {
 	unsigned int max_entries;
 };
 
+#define BPF_PROLOGUE_NRARGS_MAX                (4)
+
+unsigned int bpf_prologue_begin(char *new_prog);
+unsigned int bpf_prologue_end(char *new_prog, int nargs);
+unsigned int bpf_prologue_arg_deref(int offset,
+				int stack_index,
+				int depth,
+				char *new_prog,
+				bool last);
+
 #endif
-- 
1.8.5.2


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

* [RFC PATCH v2 08/15] bpf tools: Fetch calling regs to bpf arglist
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (6 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 07/15] bpf tools: Convert arglist to bpf prologue He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo He Kuang
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

For generating bpf prologue which fetches function formal parameters
when debuginfo is not provided.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/lib/bpf/gen_prologue.c | 19 +++++++++++++++++++
 tools/lib/bpf/libbpf.h       |  2 ++
 2 files changed, 21 insertions(+)

diff --git a/tools/lib/bpf/gen_prologue.c b/tools/lib/bpf/gen_prologue.c
index ca8aa1c..d25693a 100644
--- a/tools/lib/bpf/gen_prologue.c
+++ b/tools/lib/bpf/gen_prologue.c
@@ -106,3 +106,22 @@ unsigned int bpf_prologue_end(char *new_prog, int nargs)
 
 	return (char *)new_insn - new_prog;
 }
+
+unsigned int bpf_prologue_formal_parameters(char *new_prog, int offset,
+					int index)
+{
+	struct bpf_insn *new_insn;
+
+	if (index >= BPF_PROLOGUE_NRARGS_MAX)
+		return 0;
+
+	new_insn = (struct bpf_insn *)new_prog;
+
+	/* load ctx to r3 */
+	if (new_prog)
+		*new_insn = BPF_LDX_MEM(BPF_DW, BPF_REG_ARG2 + index,
+				BPF_REG_ARG1, offset);
+	new_insn++;
+
+	return (char *)new_insn - new_prog;
+}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index cf22a6a..9d6d4f7 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -72,5 +72,7 @@ unsigned int bpf_prologue_arg_deref(int offset,
 				int depth,
 				char *new_prog,
 				bool last);
+unsigned int bpf_prologue_formal_parameters(char *new_prog, int offset,
+					int index);
 
 #endif
-- 
1.8.5.2


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

* [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (7 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 08/15] bpf tools: Fetch calling regs to bpf arglist He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:49   ` Masami Hiramatsu
  2015-05-24  8:28 ` [RFC PATCH v2 10/15] perf bpf: Process debuginfo for generating bpf prologue He Kuang
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

When probing at function entry, fallback $params to calling regs if no
debuginfo is provided.

Before this path:
  $ perf probe -v --add='generic_perform_write $params'
  ...
  Added new event:
  Writing event: p:probe/generic_perform_write _stext+1246632 $params
  [86152.161204] Parse error at argument[0]. (-22)
  Failed to write event: Invalid argument
    Error: Failed to add events. Reason: Invalid argument (Code: -22)

After this patch:
  $ perf probe -v --add='generic_perform_write $params'
  ...
  Could not open debuginfo. Try to use symbols.
  ...
  Added new event:
  Writing event: p:probe/generic_perform_write _stext+1246632 %di %si %dx %cx %r8 %r9
    probe:generic_perform_write (on generic_perform_write with $params)

  You can now use it in all perf tools, such as:

    perf record -e probe:generic_perform_write -aR sleep 1

  $ perf record -e probe:generic_perform_write dd if=/dev/zero of=/mnt/data/test bs=4k count=3

  $ perf script
  dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x0 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
  dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x1000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
  dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x2000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/probe-event.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index d05b77c..7f9f431 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -46,6 +46,7 @@
 #include "probe-event.h"
 #include "probe-finder.h"
 #include "session.h"
+#include <dwarf-regs.h>
 
 #define MAX_CMDLEN 256
 #define PERFPROBE_GROUP "probe"
@@ -286,6 +287,14 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
 		clear_probe_trace_event(tevs + i);
 }
 
+static bool perf_probe_is_function_entry(struct perf_probe_event *pev)
+{
+	if (pev->point.file || pev->point.line || pev->point.lazy_line)
+		return false;
+
+	return true;
+}
+
 #ifdef HAVE_DWARF_SUPPORT
 /*
  * Some binaries like glibc have special symbols which are on the symbol
@@ -1225,6 +1234,33 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 	return 0;
 }
 
+static char *parse_perf_probe_param(void)
+{
+	int i = 0;
+	struct strbuf sb;
+	bool first = true;
+	const char *reg_str;
+
+	strbuf_init(&sb, 16);
+
+	while (1) {
+		reg_str = get_arch_calling_reg_str(i++);
+		if (!reg_str)
+			break;
+
+		if (first) {
+			strbuf_addf(&sb, "%s", reg_str);
+			first = false;
+		} else
+			strbuf_addf(&sb, " %s", reg_str);
+	}
+
+	if (first)
+		strbuf_add(&sb, "", 1);
+
+	return strbuf_detach(&sb, NULL);
+}
+
 /* Parse perf-probe event argument */
 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
 {
@@ -2543,6 +2579,12 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
 				goto nomem_out;
 		}
 		for (i = 0; i < tev->nargs; i++) {
+			if (perf_probe_is_function_entry(pev) &&
+				!strcmp(pev->args[i].var, "$params")) {
+				tev->args[i].value = parse_perf_probe_param();
+				continue;
+			}
+
 			if (pev->args[i].name)
 				tev->args[i].name =
 					strdup_or_goto(pev->args[i].name,
-- 
1.8.5.2


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

* [RFC PATCH v2 10/15] perf bpf: Process debuginfo for generating bpf prologue
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (8 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 11/15] perf bpf: Synthesize vars to generate " He Kuang
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Process debuginfo for bpf prologue, the process function is copied and
modified from debuginfo__find_trace_events(), with a different callback
function for generating bpf prologue bytecode.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/probe-event.c  | 27 ++++++++++++
 tools/perf/util/probe-event.h  |  2 +
 tools/perf/util/probe-finder.c | 93 ++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/probe-finder.h |  4 ++
 4 files changed, 126 insertions(+)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 7f9f431..ccbf4d9 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -914,6 +914,33 @@ out:
 	return ret;
 }
 
+int get_bpf_prologue(struct perf_probe_event *pev, char **result, int *count)
+{
+	int ret;
+	struct debuginfo *dinfo;
+	bool need_dwarf;
+
+	ret = init_symbol_maps(false);
+	if (ret < 0)
+		return ret;
+
+	need_dwarf = perf_probe_event_need_dwarf(pev);
+
+	dinfo = open_debuginfo(NULL, !need_dwarf);
+
+	if (!dinfo) {
+		if (need_dwarf)
+			return -ENOENT;
+		pr_debug("Could not open debuginfo. Try to use symbols.\n");
+		return 0;
+	}
+
+	pr_debug("Try to generate bpf prologue from debuginfo.\n");
+
+	ret = debuginfo__find_bpf_prologue(dinfo, pev, result, count);
+
+	return ret;
+}
 #else	/* !HAVE_DWARF_SUPPORT */
 
 static int
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 6c19395..3eb0183 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -106,6 +106,8 @@ extern char *synthesize_perf_probe_command(struct perf_probe_event *pev);
 extern char *synthesize_probe_trace_command(struct probe_trace_event *tev);
 extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf,
 				     size_t len);
+extern int get_bpf_prologue(struct perf_probe_event *pev,
+			char **result, int *count);
 
 /* Check the perf_probe_event needs debuginfo */
 extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 4de7649..6785eab 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -39,6 +39,7 @@
 #include "util.h"
 #include "symbol.h"
 #include "probe-finder.h"
+#include <bpf/libbpf.h>
 
 /* Kprobe tracer basic type is up to u64 */
 #define MAX_BASIC_TYPE_BITS	64
@@ -1177,6 +1178,70 @@ static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
 	return n;
 }
 
+static int generate_bpf_prologue(Dwarf_Die *sc_die, struct probe_finder *pf)
+{
+	struct trace_event_finder *tf =
+			container_of(pf, struct trace_event_finder, pf);
+	struct probe_trace_event *tev;
+	struct perf_probe_arg *args;
+	int ret, i;
+	Dwarf_Die vr_die;
+
+	/* Check number of tevs */
+	if (tf->ntevs == tf->max_tevs) {
+		pr_warning("Too many( > %d) probe point found.\n",
+			   tf->max_tevs);
+		return -ERANGE;
+	}
+	tev = &tf->tevs[tf->ntevs++];
+
+	/* Expand special probe argument if exist */
+	args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
+	if (args == NULL)
+		return -ENOMEM;
+
+	ret = expand_probe_args(sc_die, pf, args);
+	if (ret <= 0)
+		goto end;
+
+	/* restrict nargs <= BPF_PROLOGUE_NRARGS_MAX */
+	if (ret > BPF_PROLOGUE_NRARGS_MAX)
+		ret = BPF_PROLOGUE_NRARGS_MAX;
+
+	tev->nargs = ret;
+	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
+	if (tev->args == NULL) {
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	/* Find each argument */
+	for (i = 0; i < tev->nargs; i++) {
+		pf->pvar = &args[i];
+		pf->tvar = &tev->args[i];
+
+		/* Search child die for local variables and parameters. */
+		if (!die_find_variable_at(sc_die, pf->pvar->var,
+						pf->addr, &vr_die)) {
+			/* Search again in global variables */
+			if (!die_find_variable_at(&pf->cu_die, pf->pvar->var,
+							0, &vr_die)) {
+				pr_warning("Failed to find '%s' in this function.\n",
+					pf->pvar->var);
+				ret = -ENOENT;
+			}
+		}
+
+		if (ret >= 0)
+			ret = convert_variable(&vr_die, pf);
+		if (ret != 0)
+			break;
+	}
+end:
+	free(args);
+	return ret;
+}
+
 /* Add a found probe point into trace event list */
 static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
 {
@@ -1261,6 +1326,34 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
 	return (ret < 0) ? ret : tf.ntevs;
 }
 
+#define BPF_MAX_TEVS	(1)
+int debuginfo__find_bpf_prologue(struct debuginfo *dbg,
+				struct perf_probe_event *pev,
+				char **result, int *count)
+{
+	struct trace_event_finder tf = {
+			.pf = {.pev = pev, .callback = generate_bpf_prologue},
+			.mod = dbg->mod, .max_tevs = BPF_MAX_TEVS};
+	struct probe_trace_event *tevs;
+	int ret;
+
+	/* Allocate result tevs array */
+	tevs = zalloc(sizeof(struct probe_trace_event) * BPF_MAX_TEVS);
+	if (tevs == NULL)
+		return -ENOMEM;
+
+	tf.tevs = tevs;
+	tf.ntevs = 0;
+
+	ret = debuginfo__find_probes(dbg, &tf.pf);
+
+	*result = NULL;
+	*count = 0;
+
+	free(tevs);
+	return ret;
+}
+
 #define MAX_VAR_LEN 64
 
 /* Collect available variables in this scope */
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index f53553d..f046c63 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -43,6 +43,10 @@ extern int debuginfo__find_trace_events(struct debuginfo *dbg,
 					struct probe_trace_event **tevs,
 					int max_tevs);
 
+extern int debuginfo__find_bpf_prologue(struct debuginfo *dbg,
+					struct perf_probe_event *pev,
+					char **result, int *count);
+
 /* Find a perf_probe_point from debuginfo */
 extern int debuginfo__find_probe_point(struct debuginfo *dbg,
 				       unsigned long addr,
-- 
1.8.5.2


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

* [RFC PATCH v2 11/15] perf bpf: Synthesize vars to generate bpf prologue
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (9 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 10/15] perf bpf: Process debuginfo for generating bpf prologue He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 12/15] perf bpf: Generate bpf prologue without debuginfo He Kuang
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

After gethered all vars represented in trace_probe_arg, we can now use
functions in libbpf to generate the args prologue.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/probe-finder.c | 83 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 6785eab..455ff0f 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1242,6 +1242,67 @@ end:
 	return ret;
 }
 
+/*
+ * Convert args to bpf prologue
+ * 1) First pass for calculating the new program length:
+ *   synthesize_probe_bpf(arg, nargs, NULL, &new_len);
+ *
+ * 2) 2nd pass do the actually convert
+ *   new_prog = malloc(sizeof(struct bpf_insn) * new_len);
+ *   synthesize_probe_bpf(arg, nargs, new_prog, &new_len);
+ */
+static int synthesize_probe_bpf(struct probe_trace_arg *arg,
+				int nargs,
+				char *new_prog,
+				int *new_len)
+{
+	int i;
+	char *new_insn = new_prog;
+
+	if (nargs == 0) {
+		*new_len = 0;
+		return 0;
+	}
+
+	new_insn += bpf_prologue_begin(new_prog);
+	/* Find each argument */
+	for (i = 0; i < nargs; i++) {
+		struct probe_trace_arg_ref *ref = arg[i].ref;
+		unsigned int regn = arg[i].regn;
+
+		/* Print argument value */
+		if (arg[i].value[0] == '@' && ref) {
+			/* TODO parse other arguments */
+			pr_debug("%d%+ld", regn, ref->offset);
+		} else {
+			int depth = 0;
+
+			new_insn += bpf_prologue_arg_deref(
+				get_arch_reg_offset(regn),
+				i + 1,
+				depth++,
+				new_prog ? new_insn : NULL,
+				!ref);
+
+			while (ref) {
+				new_insn += bpf_prologue_arg_deref(
+					ref->offset,
+					i + 1,
+					depth++,
+					new_prog ? new_insn : NULL,
+					!ref->next);
+				ref = ref->next;
+			}
+		}
+	}
+
+	new_insn += bpf_prologue_end(new_prog ? new_insn : NULL,
+					nargs);
+	*new_len = new_insn - new_prog;
+
+	return 0;
+}
+
 /* Add a found probe point into trace event list */
 static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
 {
@@ -1335,6 +1396,8 @@ int debuginfo__find_bpf_prologue(struct debuginfo *dbg,
 			.pf = {.pev = pev, .callback = generate_bpf_prologue},
 			.mod = dbg->mod, .max_tevs = BPF_MAX_TEVS};
 	struct probe_trace_event *tevs;
+	struct probe_trace_event *tev;
+	char *new_prog;
 	int ret;
 
 	/* Allocate result tevs array */
@@ -1347,9 +1410,25 @@ int debuginfo__find_bpf_prologue(struct debuginfo *dbg,
 
 	ret = debuginfo__find_probes(dbg, &tf.pf);
 
-	*result = NULL;
-	*count = 0;
+	tev = &tevs[0];
+
+	synthesize_probe_bpf(tev->args, tev->nargs, NULL, count);
+	if (*count == 0)
+		goto end;
+
+	new_prog = malloc(*count);
+	if (!new_prog) {
+		ret = -ENOMEM;
+		goto end;
+	}
 
+	synthesize_probe_bpf(tev->args, tev->nargs, new_prog, count);
+
+	/* assign result to tvar */
+	*result = (char *)new_prog;
+
+end:
+	/* release tevs */
 	free(tevs);
 	return ret;
 }
-- 
1.8.5.2


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

* [RFC PATCH v2 12/15] perf bpf: Generate bpf prologue without debuginfo
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (10 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 11/15] perf bpf: Synthesize vars to generate " He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 13/15] perf bpf: Combine bpf prologue and bpf prog He Kuang
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

When probing at function entry, fallback to generate bpf prologue by
calling args if '$param' is the only args and no debuginfo is provided.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/probe-event.c | 54 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index ccbf4d9..0de5879 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -46,6 +46,7 @@
 #include "probe-event.h"
 #include "probe-finder.h"
 #include "session.h"
+#include <bpf/libbpf.h>
 #include <dwarf-regs.h>
 
 #define MAX_CMDLEN 256
@@ -287,6 +288,45 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
 		clear_probe_trace_event(tevs + i);
 }
 
+static int convert_parameters_to_bpf_prologue(char *new_prog, int *new_len)
+{
+	char *new_insn = new_prog;
+	int i;
+	int offset;
+
+	/* Find each argument */
+	for (i = 0; i < BPF_PROLOGUE_NRARGS_MAX; i++) {
+		offset = get_arch_calling_reg_offset(i);
+		if (offset < 0)
+			break;
+
+		new_insn += bpf_prologue_formal_parameters(
+			new_prog ? new_insn : NULL,
+			offset, i);
+	}
+	*new_len = new_insn - new_prog;
+
+	return 0;
+}
+
+static int get_bpf_prologue_default(char **result, int *count)
+{
+	char *new_prog;
+
+	convert_parameters_to_bpf_prologue(NULL, count);
+	if (*count == 0)
+		return 0;
+
+	new_prog = malloc(*count);
+	if (!new_prog)
+		return -ENOMEM;
+
+	convert_parameters_to_bpf_prologue(new_prog, count);
+	*result = (char *)new_prog;
+
+	return 0;
+}
+
 static bool perf_probe_is_function_entry(struct perf_probe_event *pev)
 {
 	if (pev->point.file || pev->point.line || pev->point.lazy_line)
@@ -931,7 +971,13 @@ int get_bpf_prologue(struct perf_probe_event *pev, char **result, int *count)
 	if (!dinfo) {
 		if (need_dwarf)
 			return -ENOENT;
-		pr_debug("Could not open debuginfo. Try to use symbols.\n");
+		pr_debug("Could not open debuginfo. Generate default prologue.\n");
+
+		if (perf_probe_is_function_entry(pev) &&
+			pev->nargs == 1 &&
+			!strcmp(pev->args[0].var, "$params"))
+			return get_bpf_prologue_default(result, count);
+
 		return 0;
 	}
 
@@ -943,6 +989,12 @@ int get_bpf_prologue(struct perf_probe_event *pev, char **result, int *count)
 }
 #else	/* !HAVE_DWARF_SUPPORT */
 
+int get_bpf_prologue(struct perf_probe_event *pev __maybe_unused,
+		char **result, int *count)
+{
+	return -ENOTSUP;
+}
+
 static int
 find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused,
 				 struct perf_probe_point *pp __maybe_unused,
-- 
1.8.5.2


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

* [RFC PATCH v2 13/15] perf bpf: Combine bpf prologue and bpf prog
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (11 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 12/15] perf bpf: Generate bpf prologue without debuginfo He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 14/15] samples/bpf: Add sample for testing bpf fetch args He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 15/15] samples/bpf: Add sample for no-debuginfo case He Kuang
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Combine bpf prologue before attaching bpf progs to perf probe event. If
prologue is generated, it will be pasted in front of the original bpf
prog.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/lib/bpf/libbpf.c       | 27 +++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h       |  2 ++
 tools/perf/util/bpf-loader.c | 27 +++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 89c725a..c0b792f 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1087,3 +1087,30 @@ int bpf_prog_get_fd(struct bpf_prog_handler *handler, int *pfd)
 	*pfd = prog->fd;
 	return 0;
 }
+
+int bpf_obj_prologue(struct bpf_prog_handler *handler, char *result, int size)
+{
+	struct bpf_program *prog;
+	int new_count;
+	int count = size / sizeof(struct bpf_insn);
+
+	prog = handler_to_prog(handler);
+	if (!prog)
+		return -EINVAL;
+
+	new_count = prog->insns_cnt + count;
+	result = realloc(result,
+			new_count * sizeof(struct bpf_insn));
+	if (!result)
+		return -ENOMEM;
+
+	memcpy(result + count * sizeof(struct bpf_insn),
+		prog->insns,
+		prog->insns_cnt * sizeof(struct bpf_insn));
+
+	free(prog->insns);
+	prog->insns = (struct bpf_insn *)result;
+	prog->insns_cnt = new_count;
+
+	return 0;
+}
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 9d6d4f7..7df58fd 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -53,6 +53,8 @@ int bpf_prog_get_title(struct bpf_prog_handler *handler,
 
 int bpf_prog_get_fd(struct bpf_prog_handler *handler, int *pfd);
 
+int bpf_obj_prologue(struct bpf_prog_handler *handler, char *result, int count);
+
 /*
  * packed attribute is unnecessary for 'bpf_map_def'.
  */
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index b793c69..3f93d04 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -168,6 +168,31 @@ void bpf_clear(void)
 		bpf_close_object(params.objects[i]);
 }
 
+static int bpf_prologue(void)
+{
+	int i, ret;
+
+	for (i = 0; i < (int)params.nr_progs; i++) {
+		struct bpf_prog_handler *prog =
+			params.progs[i].prog;
+		struct perf_probe_event *pevent =
+			params.progs[i].pevent;
+		int count;
+		char *result;
+
+		ret = get_bpf_prologue(pevent, &result, &count);
+		if (ret)
+			return ret;
+
+		if (count > 0)
+			ret = bpf_obj_prologue(prog, result, count);
+		else
+			pr_debug("bpf: no prologue generated\n");
+	}
+
+	return ret;
+}
+
 static bool is_probing = false;
 
 int bpf_unprobe(void)
@@ -220,6 +245,8 @@ int bpf_load(void)
 	size_t i;
 	int err;
 
+	bpf_prologue();
+
 	for (i = 0; i < params.nr_objects; i++) {
 		err = bpf_load_object(params.objects[i]);
 		if (err) {
-- 
1.8.5.2


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

* [RFC PATCH v2 14/15] samples/bpf: Add sample for testing bpf fetch args
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (12 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 13/15] perf bpf: Combine bpf prologue and bpf prog He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-24  8:28 ` [RFC PATCH v2 15/15] samples/bpf: Add sample for no-debuginfo case He Kuang
  14 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Sample code for testing bpf fetch args.

Works as following steps:

  $ perf bpf record --object sample_bpf_fetch_args.o -- dd if=/dev/zero of=/mnt/data/test bs=4k count=3

show result in ringbuffer:

  $ perf script
  dd  1176 [000] 87706.975390: perf_bpf_probe:generic_perform_write: (ffffffff811307ea) a_ops=0xffffffff81a200e0 bytes=0x1000 page=0xffff88007c61fd80 pos=0
  dd  1176 [000] 87706.975390: perf_bpf_probe:generic_perform_write: (ffffffff811307ea) a_ops=0xffffffff81a200e0 bytes=0x1000 page=0xffffea0001c44800 pos=4096
  dd  1176 [000] 87706.975390: perf_bpf_probe:generic_perform_write: (ffffffff811307ea) a_ops=0xffffffff81a200e0 bytes=0x1000 page=0xffffea0001ed24c0 pos=8192
  dd  1176 [000] 87706.975390: perf_bpf_probe:submit_bio: (ffffffff81310cdf) count=0x3000 rw=1 bio=0xffff88007c237a80

show result in bpf prog:

  $ cat /sys/kernel/debug/tracing/trace |grep dd
  dd-1176  [000] d... 87778.531511: : generic_perform_write(1): a_ops=ffffffff81a200e0, bytes=4096
  dd-1176  [000] d... 87778.531550: : generic_perform_write(2): page =ffff88007c61fd80, pos  =0
  dd-1176  [000] d... 87778.532142: : generic_perform_write(1): a_ops=ffffffff81a200e0, bytes=4096
  dd-1176  [000] d... 87778.532154: : generic_perform_write(2): page =ffffea0001c44800, pos  =4096
  dd-1176  [000] d... 87778.532342: : generic_perform_write(1): a_ops=ffffffff81a200e0, bytes=4096
  dd-1176  [000] d... 87778.532354: : generic_perform_write(2): page =ffffea0001ed24c0, pos  =8192
  dd-1176  [000] d.h. 87778.533049: : submit_bio count=12288, rw=1, bio=ffff88007c237a80

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 samples/bpf/Makefile                |  1 +
 samples/bpf/sample_bpf_fetch_args.c | 62 +++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)
 create mode 100644 samples/bpf/sample_bpf_fetch_args.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 8fdbd73..dc0b0e8 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -30,6 +30,7 @@ always += tracex2_kern.o
 always += tracex3_kern.o
 always += tracex4_kern.o
 always += tcbpf1_kern.o
+always += sample_bpf_fetch_args.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
diff --git a/samples/bpf/sample_bpf_fetch_args.c b/samples/bpf/sample_bpf_fetch_args.c
new file mode 100644
index 0000000..5d2c80c
--- /dev/null
+++ b/samples/bpf/sample_bpf_fetch_args.c
@@ -0,0 +1,62 @@
+/*
+  Sample code for bpf_fetch_args().
+*/
+
+#include <linux/writeback.h>
+#include <linux/blkdev.h>
+
+#include <uapi/linux/bpf.h>
+#include <linux/version.h>
+#include "bpf_helpers.h"
+
+/*
+ * Prototype:
+ * ssize_t generic_perform_write(struct file *file,
+ *				struct iov_iter *i, loff_t pos)
+ * Local variables:
+ *	const struct address_space_operations *a_ops;
+ *	unsigned long bytes;
+ *	struct page *page;
+ *	loff_t pos;
+ */
+SEC("generic_perform_write=generic_perform_write+122 file->f_mapping->a_ops bytes page pos")
+int NODE_generic_perform_write(struct pt_regs *ctx,
+			void *a_ops,
+			void *bytes,
+			void *page,
+			void *pos)
+{
+	/* Too many args for bpf_trace_printk, show in 2 lines */
+	char fmt1[] = "generic_perform_write(1): a_ops=%p, bytes=%lu\n";
+	char fmt2[] = "generic_perform_write(2): page =%p, pos  =%lu\n";
+
+	bpf_trace_printk(fmt1, sizeof(fmt1),
+			a_ops, (unsigned long)bytes);
+	bpf_trace_printk(fmt2, sizeof(fmt2),
+			page, (unsigned long)pos);
+
+	return 1;
+}
+
+/*
+ * Prototype:
+ * void submit_bio(int rw, struct bio *bio)
+ * Local variables:
+ *	unsigned int count;
+ */
+SEC("submit_bio=submit_bio+63 count rw bio")
+int NODE_submit_bio(struct pt_regs *ctx,
+			void *count,
+			void *rw,
+			void *bio)
+{
+	char fmt[] = "submit_bio count=%u, rw=%d, bio=%p\n";
+
+	bpf_trace_printk(fmt, sizeof(fmt),
+			(unsigned int)count, (int)rw, bio);
+
+	return 1;
+}
+
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
-- 
1.8.5.2


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

* [RFC PATCH v2 15/15] samples/bpf: Add sample for no-debuginfo case
  2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
                   ` (13 preceding siblings ...)
  2015-05-24  8:28 ` [RFC PATCH v2 14/15] samples/bpf: Add sample for testing bpf fetch args He Kuang
@ 2015-05-24  8:28 ` He Kuang
  2015-05-26 17:53   ` Alexei Starovoitov
  14 siblings, 1 reply; 34+ messages in thread
From: He Kuang @ 2015-05-24  8:28 UTC (permalink / raw)
  To: wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung, jolsa,
	ast, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

Sample code for testing bpf fetch args without debuginfo.

Works as following steps:

  $ perf bpf record --object /mnt/9p/sample_bpf_fetch_args_without_debug.o -- dd if=/dev/zero of=/mnt/data/test bs=4k count=3

show result in ringbuffer:
  $ perf script
  dd  1183 [000] 88000.240137: perf_bpf_probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c36cb00 arg2=0xffff88007c167e70 arg3=0x0 arg4=0x0 arg5=0x55617215 arg6=0x1839010
  dd  1183 [000] 88000.240137: perf_bpf_probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c36cb00 arg2=0xffff88007c167e70 arg3=0x1000 arg4=0x0 arg5=0x55617215 arg6=0x1839010
  dd  1183 [000] 88000.240137: perf_bpf_probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c36cb00 arg2=0xffff88007c167e70 arg3=0x2000 arg4=0x0 arg5=0x55617215 arg6=0x1839010
  dd  1183 [000] 88000.240137: perf_bpf_probe:submit_bio: (ffffffff81310ca0) arg1=0x1 arg2=0xffff88007c9d8000 arg3=0x8b9 arg4=0x8ba arg5=0x1b8e0 arg6=0xffff88007fc1b8e0

show result in bpf prog:

  $ cat /sys/kernel/debug/tracing/trace | grep dd-
  dd-1183  [000] d... 88072.038971: : generic_perform_write: file=ffff88007c36cb00, i=ffff88007c167e70, pos=0
  dd-1183  [000] d... 88072.039625: : generic_perform_write: file=ffff88007c36cb00, i=ffff88007c167e70, pos=4096
  dd-1183  [000] d... 88072.039833: : generic_perform_write: file=ffff88007c36cb00, i=ffff88007c167e70, pos=8192
  dd-1183  [000] d... 88072.040533: : submit_bio rw=1, bio=ffff88007c9d8000

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 samples/bpf/Makefile                              |  1 +
 samples/bpf/sample_bpf_fetch_args_without_debug.c | 49 +++++++++++++++++++++++
 2 files changed, 50 insertions(+)
 create mode 100644 samples/bpf/sample_bpf_fetch_args_without_debug.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index dc0b0e8..282c959 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -31,6 +31,7 @@ always += tracex3_kern.o
 always += tracex4_kern.o
 always += tcbpf1_kern.o
 always += sample_bpf_fetch_args.o
+always += sample_bpf_fetch_args_without_debug.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
diff --git a/samples/bpf/sample_bpf_fetch_args_without_debug.c b/samples/bpf/sample_bpf_fetch_args_without_debug.c
new file mode 100644
index 0000000..69519ed
--- /dev/null
+++ b/samples/bpf/sample_bpf_fetch_args_without_debug.c
@@ -0,0 +1,49 @@
+/*
+  Sample code for bpf_fetch_args() without debuginfo.
+*/
+
+#include <linux/writeback.h>
+#include <linux/blkdev.h>
+
+#include <uapi/linux/bpf.h>
+#include <linux/version.h>
+#include "bpf_helpers.h"
+
+/*
+ * Prototype:
+ * ssize_t generic_perform_write(struct file *file,
+ *			struct iov_iter *i, loff_t pos)
+ */
+SEC("generic_perform_write=generic_perform_write $params")
+int NODE_generic_perform_write(struct pt_regs *ctx,
+			void *file,
+			void *i,
+			void *pos)
+{
+	char fmt[] = "generic_perform_write: file=%p, i=%p, pos=%lu\n";
+
+	bpf_trace_printk(fmt, sizeof(fmt),
+			file, i, (unsigned long)pos);
+
+	return 1;
+}
+
+/*
+ * Prototype:
+ * void submit_bio(int rw, struct bio *bio)
+ */
+SEC("submit_bio=submit_bio $params")
+int NODE_submit_bio(struct pt_regs *ctx,
+			void *rw,
+			void *bio)
+{
+	char fmt[] = "submit_bio rw=%d, bio=%p\n";
+
+	bpf_trace_printk(fmt, sizeof(fmt),
+			(int)rw, bio);
+
+	return 1;
+}
+
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
-- 
1.8.5.2


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-24  8:28 ` [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo He Kuang
@ 2015-05-24  8:49   ` Masami Hiramatsu
  2015-05-25  8:33     ` He Kuang
  0 siblings, 1 reply; 34+ messages in thread
From: Masami Hiramatsu @ 2015-05-24  8:49 UTC (permalink / raw)
  To: He Kuang, wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung,
	jolsa, ast, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

On 2015/05/24 17:28, He Kuang wrote:
> When probing at function entry, fallback $params to calling regs if no
> debuginfo is provided.
> 
> Before this path:
>   $ perf probe -v --add='generic_perform_write $params'
>   ...
>   Added new event:
>   Writing event: p:probe/generic_perform_write _stext+1246632 $params
>   [86152.161204] Parse error at argument[0]. (-22)
>   Failed to write event: Invalid argument
>     Error: Failed to add events. Reason: Invalid argument (Code: -22)
> 
> After this patch:
>   $ perf probe -v --add='generic_perform_write $params'
>   ...
>   Could not open debuginfo. Try to use symbols.
>   ...
>   Added new event:
>   Writing event: p:probe/generic_perform_write _stext+1246632 %di %si %dx %cx %r8 %r9
>     probe:generic_perform_write (on generic_perform_write with $params)
> 
>   You can now use it in all perf tools, such as:
> 
>     perf record -e probe:generic_perform_write -aR sleep 1
> 
>   $ perf record -e probe:generic_perform_write dd if=/dev/zero of=/mnt/data/test bs=4k count=3

NAK, this should not work on x86-32 and we don't know how many registers are used.
I think $params special handler should be used only with debuginfo, since $params
ensures user to save function parameters with its name. If we can't do that, we
should accept that.

If you need to handle register arguments, you should introduce new $regparams instead
of $params. (however, that still not work correctly on x86-32)

Hmm, we also need $regs to record all registers.

Thank you,


> 
>   $ perf script
>   dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x0 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>   dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x1000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>   dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x2000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
> 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/perf/util/probe-event.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index d05b77c..7f9f431 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -46,6 +46,7 @@
>  #include "probe-event.h"
>  #include "probe-finder.h"
>  #include "session.h"
> +#include <dwarf-regs.h>
>  
>  #define MAX_CMDLEN 256
>  #define PERFPROBE_GROUP "probe"
> @@ -286,6 +287,14 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
>  		clear_probe_trace_event(tevs + i);
>  }
>  
> +static bool perf_probe_is_function_entry(struct perf_probe_event *pev)
> +{
> +	if (pev->point.file || pev->point.line || pev->point.lazy_line)
> +		return false;
> +
> +	return true;
> +}
> +
>  #ifdef HAVE_DWARF_SUPPORT
>  /*
>   * Some binaries like glibc have special symbols which are on the symbol
> @@ -1225,6 +1234,33 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
>  	return 0;
>  }
>  
> +static char *parse_perf_probe_param(void)
> +{
> +	int i = 0;
> +	struct strbuf sb;
> +	bool first = true;
> +	const char *reg_str;
> +
> +	strbuf_init(&sb, 16);
> +
> +	while (1) {
> +		reg_str = get_arch_calling_reg_str(i++);
> +		if (!reg_str)
> +			break;
> +
> +		if (first) {
> +			strbuf_addf(&sb, "%s", reg_str);
> +			first = false;
> +		} else
> +			strbuf_addf(&sb, " %s", reg_str);
> +	}
> +
> +	if (first)
> +		strbuf_add(&sb, "", 1);
> +
> +	return strbuf_detach(&sb, NULL);
> +}
> +
>  /* Parse perf-probe event argument */
>  static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
>  {
> @@ -2543,6 +2579,12 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>  				goto nomem_out;
>  		}
>  		for (i = 0; i < tev->nargs; i++) {
> +			if (perf_probe_is_function_entry(pev) &&
> +				!strcmp(pev->args[i].var, "$params")) {
> +				tev->args[i].value = parse_perf_probe_param();
> +				continue;
> +			}
> +
>  			if (pev->args[i].name)
>  				tev->args[i].name =
>  					strdup_or_goto(pev->args[i].name,
> 


-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

* Re: [RFC PATCH v2 03/15] perf bpf: Save pt_regs info from debuginfo
  2015-05-24  8:27 ` [RFC PATCH v2 03/15] perf bpf: Save pt_regs info from debuginfo He Kuang
@ 2015-05-24 13:31   ` Masami Hiramatsu
  2015-05-25  7:38     ` He Kuang
  0 siblings, 1 reply; 34+ messages in thread
From: Masami Hiramatsu @ 2015-05-24 13:31 UTC (permalink / raw)
  To: He Kuang, wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung,
	jolsa, ast, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

On 2015/05/24 17:27, He Kuang wrote:
> Save reg number in function convert_variable_location() instead of the
> register string name, so we can fetch the target register from bpf
> context register later.

This is not needed because you can also get reg number from reg string
afterwards.

Thank you,

> 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/perf/util/include/dwarf-regs.h | 13 +++++++++++++
>  tools/perf/util/probe-event.h        |  1 +
>  tools/perf/util/probe-finder.c       | 11 +++++++++++
>  3 files changed, 25 insertions(+)
> 
> diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> index 8f14965..566ff6d 100644
> --- a/tools/perf/util/include/dwarf-regs.h
> +++ b/tools/perf/util/include/dwarf-regs.h
> @@ -2,7 +2,20 @@
>  #define _PERF_DWARF_REGS_H_
>  
>  #ifdef HAVE_DWARF_SUPPORT
> +struct arch_regs_info {
> +	const char      *name;  /* Architecture dependent register string */
> +	int             offset; /* Reg offset in struct pt_regs */
> +	int             size;   /* Reg size */
> +};
> +
> +#define ARCH_REGS_INFO(r, pt_reg_name)					\
> +	{.name	= r,							\
> +	.offset = offsetof(struct pt_regs, pt_reg_name),		\
> +	.size   = sizeof(((struct pt_regs *)0)->pt_reg_name)}		\
> +
>  const char *get_arch_regstr(unsigned int n);
> +int get_arch_reg_offset(unsigned int n);
> +int get_arch_reg_size(unsigned int n);
>  #endif
>  
>  #endif
> diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
> index d6b7834..6c19395 100644
> --- a/tools/perf/util/probe-event.h
> +++ b/tools/perf/util/probe-event.h
> @@ -29,6 +29,7 @@ struct probe_trace_arg {
>  	char				*value;	/* Base value */
>  	char				*type;	/* Type name */
>  	struct probe_trace_arg_ref	*ref;	/* Referencing offset */
> +	unsigned int                    regn;   /* Regn from dwarf */
>  };
>  
>  /* kprobe-tracer and uprobe-tracer tracing event (point + arg) */
> diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> index ee27b74..681af00 100644
> --- a/tools/perf/util/probe-finder.c
> +++ b/tools/perf/util/probe-finder.c
> @@ -159,6 +159,16 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
>  	return ref;
>  }
>  
> +int __attribute__ ((weak))
> +get_arch_reg_offset(unsigned int n __maybe_unused) {
> +	return -1;
> +}
> +
> +int __attribute__ ((weak))
> +get_arch_reg_size(unsigned int n __maybe_unused) {
> +	return -1;
> +}
> +
>  /*
>   * Convert a location into trace_arg.
>   * If tvar == NULL, this just checks variable can be converted.
> @@ -260,6 +270,7 @@ static_var:
>  		return -ERANGE;
>  	}
>  
> +	tvar->regn = regn;
>  	tvar->value = strdup(regs);
>  	if (tvar->value == NULL)
>  		return -ENOMEM;
> 


-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

* Re: [RFC PATCH v2 03/15] perf bpf: Save pt_regs info from debuginfo
  2015-05-24 13:31   ` Masami Hiramatsu
@ 2015-05-25  7:38     ` He Kuang
  0 siblings, 0 replies; 34+ messages in thread
From: He Kuang @ 2015-05-25  7:38 UTC (permalink / raw)
  To: Masami Hiramatsu, wangnan0, paulus, a.p.zijlstra, mingo, acme,
	namhyung, jolsa, ast, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel



On 2015/5/24 21:31, Masami Hiramatsu wrote:
> On 2015/05/24 17:27, He Kuang wrote:
>> Save reg number in function convert_variable_location() instead of the
>> register string name, so we can fetch the target register from bpf
>> context register later.
> 
> This is not needed because you can also get reg number from reg string
> afterwards.
> 
> Thank you,

Ok, thanks
> 
>>
>> Signed-off-by: He Kuang <hekuang@huawei.com>
>> ---
>>   tools/perf/util/include/dwarf-regs.h | 13 +++++++++++++
>>   tools/perf/util/probe-event.h        |  1 +
>>   tools/perf/util/probe-finder.c       | 11 +++++++++++
>>   3 files changed, 25 insertions(+)
>>
>> diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
>> index 8f14965..566ff6d 100644
>> --- a/tools/perf/util/include/dwarf-regs.h
>> +++ b/tools/perf/util/include/dwarf-regs.h
>> @@ -2,7 +2,20 @@
>>   #define _PERF_DWARF_REGS_H_
>>   
>>   #ifdef HAVE_DWARF_SUPPORT
>> +struct arch_regs_info {
>> +	const char      *name;  /* Architecture dependent register string */
>> +	int             offset; /* Reg offset in struct pt_regs */
>> +	int             size;   /* Reg size */
>> +};
>> +
>> +#define ARCH_REGS_INFO(r, pt_reg_name)					\
>> +	{.name	= r,							\
>> +	.offset = offsetof(struct pt_regs, pt_reg_name),		\
>> +	.size   = sizeof(((struct pt_regs *)0)->pt_reg_name)}		\
>> +
>>   const char *get_arch_regstr(unsigned int n);
>> +int get_arch_reg_offset(unsigned int n);
>> +int get_arch_reg_size(unsigned int n);
>>   #endif
>>   
>>   #endif
>> diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
>> index d6b7834..6c19395 100644
>> --- a/tools/perf/util/probe-event.h
>> +++ b/tools/perf/util/probe-event.h
>> @@ -29,6 +29,7 @@ struct probe_trace_arg {
>>   	char				*value;	/* Base value */
>>   	char				*type;	/* Type name */
>>   	struct probe_trace_arg_ref	*ref;	/* Referencing offset */
>> +	unsigned int                    regn;   /* Regn from dwarf */
>>   };
>>   
>>   /* kprobe-tracer and uprobe-tracer tracing event (point + arg) */
>> diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
>> index ee27b74..681af00 100644
>> --- a/tools/perf/util/probe-finder.c
>> +++ b/tools/perf/util/probe-finder.c
>> @@ -159,6 +159,16 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
>>   	return ref;
>>   }
>>   
>> +int __attribute__ ((weak))
>> +get_arch_reg_offset(unsigned int n __maybe_unused) {
>> +	return -1;
>> +}
>> +
>> +int __attribute__ ((weak))
>> +get_arch_reg_size(unsigned int n __maybe_unused) {
>> +	return -1;
>> +}
>> +
>>   /*
>>    * Convert a location into trace_arg.
>>    * If tvar == NULL, this just checks variable can be converted.
>> @@ -260,6 +270,7 @@ static_var:
>>   		return -ERANGE;
>>   	}
>>   
>> +	tvar->regn = regn;
>>   	tvar->value = strdup(regs);
>>   	if (tvar->value == NULL)
>>   		return -ENOMEM;
>>
> 
> 


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-24  8:49   ` Masami Hiramatsu
@ 2015-05-25  8:33     ` He Kuang
  2015-05-25 12:22       ` Masami Hiramatsu
  2015-05-26 17:50       ` Alexei Starovoitov
  0 siblings, 2 replies; 34+ messages in thread
From: He Kuang @ 2015-05-25  8:33 UTC (permalink / raw)
  To: Masami Hiramatsu, wangnan0, paulus, a.p.zijlstra, mingo, acme,
	namhyung, jolsa, ast, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

hi,

On 2015/5/24 16:49, Masami Hiramatsu wrote:
> On 2015/05/24 17:28, He Kuang wrote:
>> When probing at function entry, fallback $params to calling regs if no
>> debuginfo is provided.
>>
>> Before this path:
>>    $ perf probe -v --add='generic_perform_write $params'
>>    ...
>>    Added new event:
>>    Writing event: p:probe/generic_perform_write _stext+1246632 $params
>>    [86152.161204] Parse error at argument[0]. (-22)
>>    Failed to write event: Invalid argument
>>      Error: Failed to add events. Reason: Invalid argument (Code: -22)
>>
>> After this patch:
>>    $ perf probe -v --add='generic_perform_write $params'
>>    ...
>>    Could not open debuginfo. Try to use symbols.
>>    ...
>>    Added new event:
>>    Writing event: p:probe/generic_perform_write _stext+1246632 %di %si %dx %cx %r8 %r9
>>      probe:generic_perform_write (on generic_perform_write with $params)
>>
>>    You can now use it in all perf tools, such as:
>>
>>      perf record -e probe:generic_perform_write -aR sleep 1
>>
>>    $ perf record -e probe:generic_perform_write dd if=/dev/zero of=/mnt/data/test bs=4k count=3
> 
> NAK, this should not work on x86-32 and we don't know how many registers are used.
> I think $params special handler should be used only with debuginfo, since $params
> ensures user to save function parameters with its name. If we can't do that, we
> should accept that.
> 
> If you need to handle register arguments, you should introduce new $regparams instead

Yes, $regparam is more appropriate.

> of $params. (however, that still not work correctly on x86-32)
> 
> Hmm, we also need $regs to record all registers.

Right, I learnt regparm(3) is mandatory in x86_32, according to rules,
the first three args will go to regparm(ax, dx, cx). But we should not
refer arg1~3 to ax, dx, cx because of 64bit parameters (other reasons?).

Consider this keyword is used for generating bpf prologue which fetches
formal parameters when no debuginfo is provided, for this purpose, we can:
	1) We just help fetch the $regs or $regparms(If the keyword is
$regparms, ax/dx/cx is fetched, nothing related to args) to bpf arglists
and leave the rest things to bpf prog writer.

	2) Keep that on platforms like x86_64 and skip this feature on
platforms like x86_32.

or any other suggestions?

Thanks

> 
> Thank you,
> 
> 
>>
>>    $ perf script
>>    dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x0 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>    dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x1000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>    dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x2000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>
>> Signed-off-by: He Kuang <hekuang@huawei.com>
>> ---
>>   tools/perf/util/probe-event.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 42 insertions(+)
>>
>> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
>> index d05b77c..7f9f431 100644
>> --- a/tools/perf/util/probe-event.c
>> +++ b/tools/perf/util/probe-event.c
>> @@ -46,6 +46,7 @@
>>   #include "probe-event.h"
>>   #include "probe-finder.h"
>>   #include "session.h"
>> +#include <dwarf-regs.h>
>>   
>>   #define MAX_CMDLEN 256
>>   #define PERFPROBE_GROUP "probe"
>> @@ -286,6 +287,14 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
>>   		clear_probe_trace_event(tevs + i);
>>   }
>>   
>> +static bool perf_probe_is_function_entry(struct perf_probe_event *pev)
>> +{
>> +	if (pev->point.file || pev->point.line || pev->point.lazy_line)
>> +		return false;
>> +
>> +	return true;
>> +}
>> +
>>   #ifdef HAVE_DWARF_SUPPORT
>>   /*
>>    * Some binaries like glibc have special symbols which are on the symbol
>> @@ -1225,6 +1234,33 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
>>   	return 0;
>>   }
>>   
>> +static char *parse_perf_probe_param(void)
>> +{
>> +	int i = 0;
>> +	struct strbuf sb;
>> +	bool first = true;
>> +	const char *reg_str;
>> +
>> +	strbuf_init(&sb, 16);
>> +
>> +	while (1) {
>> +		reg_str = get_arch_calling_reg_str(i++);
>> +		if (!reg_str)
>> +			break;
>> +
>> +		if (first) {
>> +			strbuf_addf(&sb, "%s", reg_str);
>> +			first = false;
>> +		} else
>> +			strbuf_addf(&sb, " %s", reg_str);
>> +	}
>> +
>> +	if (first)
>> +		strbuf_add(&sb, "", 1);
>> +
>> +	return strbuf_detach(&sb, NULL);
>> +}
>> +
>>   /* Parse perf-probe event argument */
>>   static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
>>   {
>> @@ -2543,6 +2579,12 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>>   				goto nomem_out;
>>   		}
>>   		for (i = 0; i < tev->nargs; i++) {
>> +			if (perf_probe_is_function_entry(pev) &&
>> +				!strcmp(pev->args[i].var, "$params")) {
>> +				tev->args[i].value = parse_perf_probe_param();
>> +				continue;
>> +			}
>> +
>>   			if (pev->args[i].name)
>>   				tev->args[i].name =
>>   					strdup_or_goto(pev->args[i].name,
>>
> 
> 


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-25  8:33     ` He Kuang
@ 2015-05-25 12:22       ` Masami Hiramatsu
  2015-05-25 12:46         ` Arnaldo Carvalho de Melo
  2015-05-26 17:50       ` Alexei Starovoitov
  1 sibling, 1 reply; 34+ messages in thread
From: Masami Hiramatsu @ 2015-05-25 12:22 UTC (permalink / raw)
  To: He Kuang, wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung,
	jolsa, ast, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

On 2015/05/25 17:33, He Kuang wrote:
> hi,
> 
> On 2015/5/24 16:49, Masami Hiramatsu wrote:
>> On 2015/05/24 17:28, He Kuang wrote:
>>> When probing at function entry, fallback $params to calling regs if no
>>> debuginfo is provided.
>>>
>>> Before this path:
>>>    $ perf probe -v --add='generic_perform_write $params'
>>>    ...
>>>    Added new event:
>>>    Writing event: p:probe/generic_perform_write _stext+1246632 $params
>>>    [86152.161204] Parse error at argument[0]. (-22)
>>>    Failed to write event: Invalid argument
>>>      Error: Failed to add events. Reason: Invalid argument (Code: -22)
>>>
>>> After this patch:
>>>    $ perf probe -v --add='generic_perform_write $params'
>>>    ...
>>>    Could not open debuginfo. Try to use symbols.
>>>    ...
>>>    Added new event:
>>>    Writing event: p:probe/generic_perform_write _stext+1246632 %di %si %dx %cx %r8 %r9
>>>      probe:generic_perform_write (on generic_perform_write with $params)
>>>
>>>    You can now use it in all perf tools, such as:
>>>
>>>      perf record -e probe:generic_perform_write -aR sleep 1
>>>
>>>    $ perf record -e probe:generic_perform_write dd if=/dev/zero of=/mnt/data/test bs=4k count=3
>>
>> NAK, this should not work on x86-32 and we don't know how many registers are used.
>> I think $params special handler should be used only with debuginfo, since $params
>> ensures user to save function parameters with its name. If we can't do that, we
>> should accept that.
>>
>> If you need to handle register arguments, you should introduce new $regparams instead
> 
> Yes, $regparam is more appropriate.

thanks :)

>> of $params. (however, that still not work correctly on x86-32)
>>
>> Hmm, we also need $regs to record all registers.
> 
> Right, I learnt regparm(3) is mandatory in x86_32, according to rules,
> the first three args will go to regparm(ax, dx, cx). But we should not
> refer arg1~3 to ax, dx, cx because of 64bit parameters (other reasons?).

Also, if the function is asmlinkage, its arguments are passed via stack.

> Consider this keyword is used for generating bpf prologue which fetches
> formal parameters when no debuginfo is provided, for this purpose, we can:
> 	1) We just help fetch the $regs or $regparms(If the keyword is
> $regparms, ax/dx/cx is fetched, nothing related to args) to bpf arglists
> and leave the rest things to bpf prog writer.
> 
> 	2) Keep that on platforms like x86_64 and skip this feature on
> platforms like x86_32.

I like 1), since such arch-dependent behavior looks confusing.

> 
> or any other suggestions?

Actually, I'm working on the perf-probe cache enhancement (and it will be perf-cache)
which allows you to cache the result of debuginfo analysis under buildid-cache.
So, if the build-id is same on remote machines, you can transfer the cache to the
remote machine and reuse it. This means you don't need debuginfo in the remote machine
unless you're using the same binary/bpf.

Thank you,

> 
> Thanks
> 
>>
>> Thank you,
>>
>>
>>>
>>>    $ perf script
>>>    dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x0 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>>    dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x1000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>>    dd  1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x2000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>>
>>> Signed-off-by: He Kuang <hekuang@huawei.com>
>>> ---
>>>   tools/perf/util/probe-event.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>>   1 file changed, 42 insertions(+)
>>>
>>> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
>>> index d05b77c..7f9f431 100644
>>> --- a/tools/perf/util/probe-event.c
>>> +++ b/tools/perf/util/probe-event.c
>>> @@ -46,6 +46,7 @@
>>>   #include "probe-event.h"
>>>   #include "probe-finder.h"
>>>   #include "session.h"
>>> +#include <dwarf-regs.h>
>>>   
>>>   #define MAX_CMDLEN 256
>>>   #define PERFPROBE_GROUP "probe"
>>> @@ -286,6 +287,14 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
>>>   		clear_probe_trace_event(tevs + i);
>>>   }
>>>   
>>> +static bool perf_probe_is_function_entry(struct perf_probe_event *pev)
>>> +{
>>> +	if (pev->point.file || pev->point.line || pev->point.lazy_line)
>>> +		return false;
>>> +
>>> +	return true;
>>> +}
>>> +
>>>   #ifdef HAVE_DWARF_SUPPORT
>>>   /*
>>>    * Some binaries like glibc have special symbols which are on the symbol
>>> @@ -1225,6 +1234,33 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
>>>   	return 0;
>>>   }
>>>   
>>> +static char *parse_perf_probe_param(void)
>>> +{
>>> +	int i = 0;
>>> +	struct strbuf sb;
>>> +	bool first = true;
>>> +	const char *reg_str;
>>> +
>>> +	strbuf_init(&sb, 16);
>>> +
>>> +	while (1) {
>>> +		reg_str = get_arch_calling_reg_str(i++);
>>> +		if (!reg_str)
>>> +			break;
>>> +
>>> +		if (first) {
>>> +			strbuf_addf(&sb, "%s", reg_str);
>>> +			first = false;
>>> +		} else
>>> +			strbuf_addf(&sb, " %s", reg_str);
>>> +	}
>>> +
>>> +	if (first)
>>> +		strbuf_add(&sb, "", 1);
>>> +
>>> +	return strbuf_detach(&sb, NULL);
>>> +}
>>> +
>>>   /* Parse perf-probe event argument */
>>>   static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
>>>   {
>>> @@ -2543,6 +2579,12 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>>>   				goto nomem_out;
>>>   		}
>>>   		for (i = 0; i < tev->nargs; i++) {
>>> +			if (perf_probe_is_function_entry(pev) &&
>>> +				!strcmp(pev->args[i].var, "$params")) {
>>> +				tev->args[i].value = parse_perf_probe_param();
>>> +				continue;
>>> +			}
>>> +
>>>   			if (pev->args[i].name)
>>>   				tev->args[i].name =
>>>   					strdup_or_goto(pev->args[i].name,
>>>
>>
>>
> 
> 


-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-25 12:22       ` Masami Hiramatsu
@ 2015-05-25 12:46         ` Arnaldo Carvalho de Melo
  2015-05-25 13:06           ` Masami Hiramatsu
  0 siblings, 1 reply; 34+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-05-25 12:46 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: He Kuang, wangnan0, paulus, a.p.zijlstra, mingo, namhyung, jolsa,
	ast, dsahern, brendan.d.gregg, daniel, lizefan, linux-kernel

Em Mon, May 25, 2015 at 09:22:50PM +0900, Masami Hiramatsu escreveu:
> Actually, I'm working on the perf-probe cache enhancement (and it will be perf-cache)
> which allows you to cache the result of debuginfo analysis under buildid-cache.
> So, if the build-id is same on remote machines, you can transfer the cache to the
> remote machine and reuse it.

> This means you don't need debuginfo in the remote machine unless
> you're using the same binary/bpf.

I think this should read:

"This means you don't need debuginfo in the remote machine unless you're
using a _different_ binary/bpf"

or, alternatively:

"This means you don't need debuginfo in the remote machine _as long as_
you're using the same binary bpf"

No?

- Arnaldo

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

* Re: Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-25 12:46         ` Arnaldo Carvalho de Melo
@ 2015-05-25 13:06           ` Masami Hiramatsu
  0 siblings, 0 replies; 34+ messages in thread
From: Masami Hiramatsu @ 2015-05-25 13:06 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: He Kuang, wangnan0, paulus, a.p.zijlstra, mingo, namhyung, jolsa,
	ast, dsahern, brendan.d.gregg, daniel, lizefan, linux-kernel

On 2015/05/25 21:46, Arnaldo Carvalho de Melo wrote:
> Em Mon, May 25, 2015 at 09:22:50PM +0900, Masami Hiramatsu escreveu:
>> Actually, I'm working on the perf-probe cache enhancement (and it will be perf-cache)
>> which allows you to cache the result of debuginfo analysis under buildid-cache.
>> So, if the build-id is same on remote machines, you can transfer the cache to the
>> remote machine and reuse it.
> 
>> This means you don't need debuginfo in the remote machine unless
>> you're using the same binary/bpf.
> 
> I think this should read:
> 
> "This means you don't need debuginfo in the remote machine unless you're
> using a _different_ binary/bpf"

Oops, right. unless different one, is correct.

> 
> or, alternatively:
> 
> "This means you don't need debuginfo in the remote machine _as long as_
> you're using the same binary bpf"

Yes, thanks!

> 
> No?
> 
> - Arnaldo
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-25  8:33     ` He Kuang
  2015-05-25 12:22       ` Masami Hiramatsu
@ 2015-05-26 17:50       ` Alexei Starovoitov
  2015-05-27  2:27         ` He Kuang
  1 sibling, 1 reply; 34+ messages in thread
From: Alexei Starovoitov @ 2015-05-26 17:50 UTC (permalink / raw)
  To: He Kuang, Masami Hiramatsu, wangnan0, paulus, a.p.zijlstra,
	mingo, acme, namhyung, jolsa, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

On 5/25/15 1:33 AM, He Kuang wrote:
> Right, I learnt regparm(3) is mandatory in x86_32, according to rules,
> the first three args will go to regparm(ax, dx, cx). But we should not
> refer arg1~3 to ax, dx, cx because of 64bit parameters (other reasons?).
> 
> Consider this keyword is used for generating bpf prologue which fetches
> formal parameters when no debuginfo is provided, for this purpose, we can:
> 	1) We just help fetch the $regs or $regparms(If the keyword is
> $regparms, ax/dx/cx is fetched, nothing related to args) to bpf arglists
> and leave the rest things to bpf prog writer.
> 
> 	2) Keep that on platforms like x86_64 and skip this feature on
> platforms like x86_32.
> 
> or any other suggestions?

Single argument like $regparam or whatever name cannot work on all
architectures, that's why in the very beginning I suggested
'func(long, char, void*)' syntax to describe arguments when debuginfo
is not available. Calling convention for scalars is simple enough on
all major architectures. x64_64 - trivial, i64_32 - a bit more involved,
but simple enough so that list of types of arguments is enough to figure
out which register or register pair or stack should be used to fetch
argN.


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

* Re: [RFC PATCH v2 15/15] samples/bpf: Add sample for no-debuginfo case
  2015-05-24  8:28 ` [RFC PATCH v2 15/15] samples/bpf: Add sample for no-debuginfo case He Kuang
@ 2015-05-26 17:53   ` Alexei Starovoitov
  0 siblings, 0 replies; 34+ messages in thread
From: Alexei Starovoitov @ 2015-05-26 17:53 UTC (permalink / raw)
  To: He Kuang, wangnan0, paulus, a.p.zijlstra, mingo, acme, namhyung,
	jolsa, masami.hiramatsu.pt, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

On 5/24/15 1:28 AM, He Kuang wrote:
> +SEC("generic_perform_write=generic_perform_write $params")
> +int NODE_generic_perform_write(struct pt_regs *ctx,
> +			void *file,
> +			void *i,
> +			void *pos)

instead:
SEC("generic_perform_write(void*, void*, void*)")
int prog(struct pt_regs *ctx, void *fild, void *i, void *pos)

would be arch-independent.


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-26 17:50       ` Alexei Starovoitov
@ 2015-05-27  2:27         ` He Kuang
  2015-05-27 11:43           ` Masami Hiramatsu
  2015-05-27 15:30           ` Alexei Starovoitov
  0 siblings, 2 replies; 34+ messages in thread
From: He Kuang @ 2015-05-27  2:27 UTC (permalink / raw)
  To: Alexei Starovoitov, Masami Hiramatsu, wangnan0, paulus,
	a.p.zijlstra, mingo, acme, namhyung, jolsa, dsahern,
	brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

hi, Alexei

On 2015/5/27 1:50, Alexei Starovoitov wrote:
> On 5/25/15 1:33 AM, He Kuang wrote:
>> Right, I learnt regparm(3) is mandatory in x86_32, according to rules,
>> the first three args will go to regparm(ax, dx, cx). But we should not
>> refer arg1~3 to ax, dx, cx because of 64bit parameters (other reasons?).
>>
>> Consider this keyword is used for generating bpf prologue which fetches
>> formal parameters when no debuginfo is provided, for this purpose, we can:
>> 	1) We just help fetch the $regs or $regparms(If the keyword is
>> $regparms, ax/dx/cx is fetched, nothing related to args) to bpf arglists
>> and leave the rest things to bpf prog writer.
>>
>> 	2) Keep that on platforms like x86_64 and skip this feature on
>> platforms like x86_32.
>>
>> or any other suggestions?
> 
> Single argument like $regparam or whatever name cannot work on all
> architectures, that's why in the very beginning I suggested
> 'func(long, char, void*)' syntax to describe arguments when debuginfo
> is not available. Calling convention for scalars is simple enough on
> all major architectures. x64_64 - trivial, i64_32 - a bit more involved,
> but simple enough so that list of types of arguments is enough to figure
> out which register or register pair or stack should be used to fetch
> argN.
> 
> 
As Masami has reminded,  the use of 'asmlinkage' forces regparm=0, and
we can't destinguish them without debuginfo, so 'func(long, char,
void*)' syntax not work in everywhere.

In fact, all the context infos are there in bpf prog(pt_regs in arg1).
To the non-debuginfo case, without the help of prologue, user steps
following flow to fetch params:

1. pt_regs(arg1) + architecture => calling regs

2. calling regs + function prototype(SEC) + gcc attributes(like
asmlinkage) => formal parameters

 '$regparms' do the 1st step, though not a full workaround. But for the
lack of gcc attributes, it seems we can't do the 2nd step. Any ideas?

Thanks


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-27  2:27         ` He Kuang
@ 2015-05-27 11:43           ` Masami Hiramatsu
  2015-05-27 15:30           ` Alexei Starovoitov
  1 sibling, 0 replies; 34+ messages in thread
From: Masami Hiramatsu @ 2015-05-27 11:43 UTC (permalink / raw)
  To: He Kuang, Alexei Starovoitov, wangnan0, paulus, a.p.zijlstra,
	mingo, acme, namhyung, jolsa, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

On 2015/05/27 11:27, He Kuang wrote:
> hi, Alexei
> 
> On 2015/5/27 1:50, Alexei Starovoitov wrote:
>> On 5/25/15 1:33 AM, He Kuang wrote:
>>> Right, I learnt regparm(3) is mandatory in x86_32, according to rules,
>>> the first three args will go to regparm(ax, dx, cx). But we should not
>>> refer arg1~3 to ax, dx, cx because of 64bit parameters (other reasons?).
>>>
>>> Consider this keyword is used for generating bpf prologue which fetches
>>> formal parameters when no debuginfo is provided, for this purpose, we can:
>>> 	1) We just help fetch the $regs or $regparms(If the keyword is
>>> $regparms, ax/dx/cx is fetched, nothing related to args) to bpf arglists
>>> and leave the rest things to bpf prog writer.
>>>
>>> 	2) Keep that on platforms like x86_64 and skip this feature on
>>> platforms like x86_32.
>>>
>>> or any other suggestions?
>>
>> Single argument like $regparam or whatever name cannot work on all
>> architectures, that's why in the very beginning I suggested
>> 'func(long, char, void*)' syntax to describe arguments when debuginfo
>> is not available. Calling convention for scalars is simple enough on
>> all major architectures. x64_64 - trivial, i64_32 - a bit more involved,
>> but simple enough so that list of types of arguments is enough to figure
>> out which register or register pair or stack should be used to fetch
>> argN.
>>
>>
> As Masami has reminded,  the use of 'asmlinkage' forces regparm=0, and
> we can't destinguish them without debuginfo, so 'func(long, char,
> void*)' syntax not work in everywhere.
> 
> In fact, all the context infos are there in bpf prog(pt_regs in arg1).
> To the non-debuginfo case, without the help of prologue, user steps
> following flow to fetch params:
> 
> 1. pt_regs(arg1) + architecture => calling regs
> 
> 2. calling regs + function prototype(SEC) + gcc attributes(like
> asmlinkage) => formal parameters
> 
>  '$regparms' do the 1st step, though not a full workaround. But for the
> lack of gcc attributes, it seems we can't do the 2nd step. Any ideas?

If you don't have the debuginfo, $regparams will help, but not cover
all the cases. This just means users may need to take care of using it.
Actually, in most cases, I'm sure $regparams will work fine, since
most functions are not asmlinkage'ed.

If you consider bpf requires correct parameters, you need debuginfo or
something like it, e.g. the pre-analyzed cache of perf-probe (see
https://lkml.org/lkml/2014/10/31/207).

Thank you,

-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-27  2:27         ` He Kuang
  2015-05-27 11:43           ` Masami Hiramatsu
@ 2015-05-27 15:30           ` Alexei Starovoitov
  2015-05-28 13:01             ` He Kuang
  1 sibling, 1 reply; 34+ messages in thread
From: Alexei Starovoitov @ 2015-05-27 15:30 UTC (permalink / raw)
  To: He Kuang, Masami Hiramatsu, wangnan0, paulus, a.p.zijlstra,
	mingo, acme, namhyung, jolsa, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

On 5/26/15 7:27 PM, He Kuang wrote:
> hi, Alexei
> 
> On 2015/5/27 1:50, Alexei Starovoitov wrote:
>> On 5/25/15 1:33 AM, He Kuang wrote:
>>> Right, I learnt regparm(3) is mandatory in x86_32, according to rules,
>>> the first three args will go to regparm(ax, dx, cx). But we should not
>>> refer arg1~3 to ax, dx, cx because of 64bit parameters (other reasons?).
>>>
>>> Consider this keyword is used for generating bpf prologue which fetches
>>> formal parameters when no debuginfo is provided, for this purpose, we can:
>>> 	1) We just help fetch the $regs or $regparms(If the keyword is
>>> $regparms, ax/dx/cx is fetched, nothing related to args) to bpf arglists
>>> and leave the rest things to bpf prog writer.
>>>
>>> 	2) Keep that on platforms like x86_64 and skip this feature on
>>> platforms like x86_32.
>>>
>>> or any other suggestions?
>>
>> Single argument like $regparam or whatever name cannot work on all
>> architectures, that's why in the very beginning I suggested
>> 'func(long, char, void*)' syntax to describe arguments when debuginfo
>> is not available. Calling convention for scalars is simple enough on
>> all major architectures. x64_64 - trivial, i64_32 - a bit more involved,
>> but simple enough so that list of types of arguments is enough to figure
>> out which register or register pair or stack should be used to fetch
>> argN.
>>
>>
> As Masami has reminded,  the use of 'asmlinkage' forces regparm=0, and
> we can't destinguish them without debuginfo, so 'func(long, char,
> void*)' syntax not work in everywhere.
> 
> In fact, all the context infos are there in bpf prog(pt_regs in arg1).
> To the non-debuginfo case, without the help of prologue, user steps
> following flow to fetch params:
> 
> 1. pt_regs(arg1) + architecture => calling regs
> 
> 2. calling regs + function prototype(SEC) + gcc attributes(like
> asmlinkage) => formal parameters
> 
>   '$regparms' do the 1st step, though not a full workaround. But for the
> lack of gcc attributes, it seems we can't do the 2nd step. Any ideas?

I don't think you can break it down in two steps like this.
There is no such thing as 'calling regs'. x86_32 with ax,dx,cx
are not 'calling regs'. 64-bit values will be passed in a pair.
Only 'pt_regs + arch + func_proto + asmlinkage' makes sense
from the user point of view.
Adding 'asmlinkage' attr is also trivial.
'func(long, char) asmlinkage' is easy to parse and the user
will be able to write programs that are architecture independent.
We already have 'struct pt_regs *' and $regparams don't buy us
anything extra. It may be useful for generic kprobe, but not for bpf.


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-27 15:30           ` Alexei Starovoitov
@ 2015-05-28 13:01             ` He Kuang
  2015-05-28 18:10               ` Alexei Starovoitov
  0 siblings, 1 reply; 34+ messages in thread
From: He Kuang @ 2015-05-28 13:01 UTC (permalink / raw)
  To: Alexei Starovoitov, Masami Hiramatsu, wangnan0, paulus,
	a.p.zijlstra, mingo, acme, namhyung, jolsa, dsahern,
	brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel



On 2015/5/27 23:30, Alexei Starovoitov wrote:
> On 5/26/15 7:27 PM, He Kuang wrote:
>> hi, Alexei
>>
>> On 2015/5/27 1:50, Alexei Starovoitov wrote:
>>> On 5/25/15 1:33 AM, He Kuang wrote:
>>>> Right, I learnt regparm(3) is mandatory in x86_32, according to rules,
>>>> the first three args will go to regparm(ax, dx, cx). But we should not
>>>> refer arg1~3 to ax, dx, cx because of 64bit parameters (other reasons?).
>>>>
>>>> Consider this keyword is used for generating bpf prologue which fetches
>>>> formal parameters when no debuginfo is provided, for this purpose, we can:
>>>> 	1) We just help fetch the $regs or $regparms(If the keyword is
>>>> $regparms, ax/dx/cx is fetched, nothing related to args) to bpf arglists
>>>> and leave the rest things to bpf prog writer.
>>>>
>>>> 	2) Keep that on platforms like x86_64 and skip this feature on
>>>> platforms like x86_32.
>>>>
>>>> or any other suggestions?
>>>
>>> Single argument like $regparam or whatever name cannot work on all
>>> architectures, that's why in the very beginning I suggested
>>> 'func(long, char, void*)' syntax to describe arguments when debuginfo
>>> is not available. Calling convention for scalars is simple enough on
>>> all major architectures. x64_64 - trivial, i64_32 - a bit more involved,
>>> but simple enough so that list of types of arguments is enough to figure
>>> out which register or register pair or stack should be used to fetch
>>> argN.
>>>
>>>
>> As Masami has reminded,  the use of 'asmlinkage' forces regparm=0, and
>> we can't destinguish them without debuginfo, so 'func(long, char,
>> void*)' syntax not work in everywhere.
>>
>> In fact, all the context infos are there in bpf prog(pt_regs in arg1).
>> To the non-debuginfo case, without the help of prologue, user steps
>> following flow to fetch params:
>>
>> 1. pt_regs(arg1) + architecture => calling regs
>>
>> 2. calling regs + function prototype(SEC) + gcc attributes(like
>> asmlinkage) => formal parameters
>>
>>    '$regparms' do the 1st step, though not a full workaround. But for the
>> lack of gcc attributes, it seems we can't do the 2nd step. Any ideas?
> 
> I don't think you can break it down in two steps like this.
> There is no such thing as 'calling regs'. x86_32 with ax,dx,cx
> are not 'calling regs'. 64-bit values will be passed in a pair.
> Only 'pt_regs + arch + func_proto + asmlinkage' makes sense
> from the user point of view.
> Adding 'asmlinkage' attr is also trivial.
> 'func(long, char) asmlinkage' is easy to parse and the user

I think at this early stage, we could make our bpf variable
prologue work with debuginfo while keeping bpf 'SEC' syntax
consistent with original perf probe. After all, we can use
pt_regs directly or relay to perf-probe cache by Masami to deal
with non-debug cases.

> will be able to write programs that are architecture independent.
> We already have 'struct pt_regs *' and $regparams don't buy us
> anything extra. It may be useful for generic kprobe, but not for bpf.
> 
> 


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-28 13:01             ` He Kuang
@ 2015-05-28 18:10               ` Alexei Starovoitov
  2015-05-29  6:30                 ` He Kuang
  0 siblings, 1 reply; 34+ messages in thread
From: Alexei Starovoitov @ 2015-05-28 18:10 UTC (permalink / raw)
  To: He Kuang, Masami Hiramatsu, wangnan0, paulus, a.p.zijlstra,
	mingo, acme, namhyung, jolsa, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

On 5/28/15 6:01 AM, He Kuang wrote:
>> I don't think you can break it down in two steps like this.
>> >There is no such thing as 'calling regs'. x86_32 with ax,dx,cx
>> >are not 'calling regs'. 64-bit values will be passed in a pair.
>> >Only 'pt_regs + arch + func_proto + asmlinkage' makes sense
>> >from the user point of view.
>> >Adding 'asmlinkage' attr is also trivial.
>> >'func(long, char) asmlinkage' is easy to parse and the user
> I think at this early stage, we could make our bpf variable
> prologue work with debuginfo while keeping bpf 'SEC' syntax
> consistent with original perf probe. After all, we can use
> pt_regs directly or relay to perf-probe cache by Masami to deal
> with non-debug cases.

so you're saying you don't want to support non-debug case for now?
Sure, as long as section name parser will be able to support
'func(long, char) asmlinkage' syntax in the future without breaking
compatibility. I'm mostly interested in cases when debug info
is not available at all. So perf-probe cache is of no use to me.


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-28 18:10               ` Alexei Starovoitov
@ 2015-05-29  6:30                 ` He Kuang
  2015-05-29 23:55                   ` Masami Hiramatsu
  0 siblings, 1 reply; 34+ messages in thread
From: He Kuang @ 2015-05-29  6:30 UTC (permalink / raw)
  To: Alexei Starovoitov, Masami Hiramatsu, wangnan0, paulus,
	a.p.zijlstra, mingo, acme, namhyung, jolsa, dsahern,
	brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel

hi, Alexei

On 2015/5/29 2:10, Alexei Starovoitov wrote:
> On 5/28/15 6:01 AM, He Kuang wrote:
>>> I don't think you can break it down in two steps like this.
>>>> There is no such thing as 'calling regs'. x86_32 with ax,dx,cx
>>>> are not 'calling regs'. 64-bit values will be passed in a pair.
>>>> Only 'pt_regs + arch + func_proto + asmlinkage' makes sense
>>> >from the user point of view.
>>>> Adding 'asmlinkage' attr is also trivial.
>>>> 'func(long, char) asmlinkage' is easy to parse and the user
>> I think at this early stage, we could make our bpf variable
>> prologue work with debuginfo while keeping bpf 'SEC' syntax
>> consistent with original perf probe. After all, we can use
>> pt_regs directly or relay to perf-probe cache by Masami to deal
>> with non-debug cases.
> 
> so you're saying you don't want to support non-debug case for now?
> Sure, as long as section name parser will be able to support
> 'func(long, char) asmlinkage' syntax in the future without breaking
> compatibility. I'm mostly interested in cases when debug info
> is not available at all. So perf-probe cache is of no use to me.
> 
> 

Yes, that syntax do deal with the situation which current 'perf
probe' syntax not covered, so not only bpf prologue would benifit
from that, maybe we could try to let perf probe involve that.

Thanks.


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

* Re: Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-29  6:30                 ` He Kuang
@ 2015-05-29 23:55                   ` Masami Hiramatsu
  2015-05-30  1:27                     ` Alexei Starovoitov
  0 siblings, 1 reply; 34+ messages in thread
From: Masami Hiramatsu @ 2015-05-29 23:55 UTC (permalink / raw)
  To: He Kuang, Alexei Starovoitov, wangnan0, paulus, a.p.zijlstra,
	mingo, acme, namhyung, jolsa, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel, cti.systems-productivity-manager.ts

On 2015/05/29 15:30, He Kuang wrote:
> hi, Alexei
> 
> On 2015/5/29 2:10, Alexei Starovoitov wrote:
>> On 5/28/15 6:01 AM, He Kuang wrote:
>>>> I don't think you can break it down in two steps like this.
>>>>> There is no such thing as 'calling regs'. x86_32 with ax,dx,cx
>>>>> are not 'calling regs'. 64-bit values will be passed in a pair.
>>>>> Only 'pt_regs + arch + func_proto + asmlinkage' makes sense
>>>> >from the user point of view.
>>>>> Adding 'asmlinkage' attr is also trivial.
>>>>> 'func(long, char) asmlinkage' is easy to parse and the user
>>> I think at this early stage, we could make our bpf variable
>>> prologue work with debuginfo while keeping bpf 'SEC' syntax
>>> consistent with original perf probe. After all, we can use
>>> pt_regs directly or relay to perf-probe cache by Masami to deal
>>> with non-debug cases.
>>
>> so you're saying you don't want to support non-debug case for now?
>> Sure, as long as section name parser will be able to support
>> 'func(long, char) asmlinkage' syntax in the future without breaking
>> compatibility. I'm mostly interested in cases when debug info
>> is not available at all. So perf-probe cache is of no use to me.
>>
>>
> 
> Yes, that syntax do deal with the situation which current 'perf
> probe' syntax not covered, so not only bpf prologue would benifit
> from that, maybe we could try to let perf probe involve that.

Hmm, then how about below syntax?

 perf probe x86_acpi_enter_sleep_state $regparams:asmlinkage(char)

So, regparams has following synopsis.

 $regparams[:[asmlinkage|0-6]([u8|u16|u32|u64|ptr][,...])]

Note that asmlinkage is a synonym of 0, and default depends on arch :)
Some architecture ignores this part, e.g. x86_64 always uses regs.
And it is automatically expanded to argX="%reg or $stackX".

e.g.
 $regparams is expanded to
  arg1=%di arg2=%si arg3=%dx arg4=%cx arg5=%r8 arg6=%r9 (on x86_64)
  arg1=%ax arg2=%dx arg3=%cx arg4=$stack1 arg5=$stack2 arg6=$stack3 (on i386)

 $regparams:0 is expanded to
  arg1=%di arg2=%si arg3=%dx arg4=%cx arg5=%r8 arg6=%r9 (on x86_64)
  arg1=$stack1 arg2=$stack2 arg3=$stack3 arg4=$stack4 arg5=$stack5 arg6=$stack6 (on i386)

 $regparams:3(char,long) is expanded to
  arg1=%di:s8 arg2=%si:s64 (on x86_64)
  arg1=%ax:s8 arg2=%dx:s64 (on i386)

How is this?

Thank you,


-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-29 23:55                   ` Masami Hiramatsu
@ 2015-05-30  1:27                     ` Alexei Starovoitov
  2015-05-30  7:01                       ` Masami Hiramatsu
  0 siblings, 1 reply; 34+ messages in thread
From: Alexei Starovoitov @ 2015-05-30  1:27 UTC (permalink / raw)
  To: Masami Hiramatsu, He Kuang, wangnan0, paulus, a.p.zijlstra,
	mingo, acme, namhyung, jolsa, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel, cti.systems-productivity-manager.ts

On 5/29/15 4:55 PM, Masami Hiramatsu wrote:
> On 2015/05/29 15:30, He Kuang wrote:
>> hi, Alexei
>>
>> On 2015/5/29 2:10, Alexei Starovoitov wrote:
>>> On 5/28/15 6:01 AM, He Kuang wrote:
>>>>> I don't think you can break it down in two steps like this.
>>>>>> There is no such thing as 'calling regs'. x86_32 with ax,dx,cx
>>>>>> are not 'calling regs'. 64-bit values will be passed in a pair.
>>>>>> Only 'pt_regs + arch + func_proto + asmlinkage' makes sense
>>>>> >from the user point of view.
>>>>>> Adding 'asmlinkage' attr is also trivial.
>>>>>> 'func(long, char) asmlinkage' is easy to parse and the user
>>>> I think at this early stage, we could make our bpf variable
>>>> prologue work with debuginfo while keeping bpf 'SEC' syntax
>>>> consistent with original perf probe. After all, we can use
>>>> pt_regs directly or relay to perf-probe cache by Masami to deal
>>>> with non-debug cases.
>>>
>>> so you're saying you don't want to support non-debug case for now?
>>> Sure, as long as section name parser will be able to support
>>> 'func(long, char) asmlinkage' syntax in the future without breaking
>>> compatibility. I'm mostly interested in cases when debug info
>>> is not available at all. So perf-probe cache is of no use to me.
>>>
>>>
>>
>> Yes, that syntax do deal with the situation which current 'perf
>> probe' syntax not covered, so not only bpf prologue would benifit
>> from that, maybe we could try to let perf probe involve that.
> 
> Hmm, then how about below syntax?
> 
>   perf probe x86_acpi_enter_sleep_state $regparams:asmlinkage(char)
> 
> So, regparams has following synopsis.
> 
>   $regparams[:[asmlinkage|0-6]([u8|u16|u32|u64|ptr][,...])]

the number doesn't make sense in generic command. Only x86_32 plays
with calling convention. All other archs are not doing anything special
for asmlinkage.
I think the following is enough:
$regparams[[:asmlinkage]([u8|u16|u32|u64|ptr|char|short|long|
long long|void*][,...])]
asmlinkage most of the time won't be used and typical command will look
like: 'func=func $regparams(char, long, void*)'
which is ok for kprobe.
For bpf section name I would still prefer 'func(char, long, void*)'
since it's more concise, easier to remember, more similar to C declaration.

> Note that asmlinkage is a synonym of 0, and default depends on arch :)
> Some architecture ignores this part, e.g. x86_64 always uses regs.
> And it is automatically expanded to argX="%reg or $stackX".
> 
> e.g.
>   $regparams is expanded to
>    arg1=%di arg2=%si arg3=%dx arg4=%cx arg5=%r8 arg6=%r9 (on x86_64)
>    arg1=%ax arg2=%dx arg3=%cx arg4=$stack1 arg5=$stack2 arg6=$stack3 (on i386)
> 
>   $regparams:0 is expanded to
>    arg1=%di arg2=%si arg3=%dx arg4=%cx arg5=%r8 arg6=%r9 (on x86_64)
>    arg1=$stack1 arg2=$stack2 arg3=$stack3 arg4=$stack4 arg5=$stack5 arg6=$stack6 (on i386)
> 
>   $regparams:3(char,long) is expanded to
>    arg1=%di:s8 arg2=%si:s64 (on x86_64)
>    arg1=%ax:s8 arg2=%dx:s64 (on i386)
> 
> How is this?
> 
> Thank you,
> 
> 


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

* Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo
  2015-05-30  1:27                     ` Alexei Starovoitov
@ 2015-05-30  7:01                       ` Masami Hiramatsu
  0 siblings, 0 replies; 34+ messages in thread
From: Masami Hiramatsu @ 2015-05-30  7:01 UTC (permalink / raw)
  To: Alexei Starovoitov, He Kuang, wangnan0, paulus, a.p.zijlstra,
	mingo, acme, namhyung, jolsa, dsahern, brendan.d.gregg, daniel
  Cc: lizefan, linux-kernel, cti.systems-productivity-manager.ts

On 2015/05/30 10:27, Alexei Starovoitov wrote:
> On 5/29/15 4:55 PM, Masami Hiramatsu wrote:
>> On 2015/05/29 15:30, He Kuang wrote:
>>> hi, Alexei
>>>
>>> On 2015/5/29 2:10, Alexei Starovoitov wrote:
>>>> On 5/28/15 6:01 AM, He Kuang wrote:
>>>>>> I don't think you can break it down in two steps like this.
>>>>>>> There is no such thing as 'calling regs'. x86_32 with ax,dx,cx
>>>>>>> are not 'calling regs'. 64-bit values will be passed in a pair.
>>>>>>> Only 'pt_regs + arch + func_proto + asmlinkage' makes sense
>>>>>> >from the user point of view.
>>>>>>> Adding 'asmlinkage' attr is also trivial.
>>>>>>> 'func(long, char) asmlinkage' is easy to parse and the user
>>>>> I think at this early stage, we could make our bpf variable
>>>>> prologue work with debuginfo while keeping bpf 'SEC' syntax
>>>>> consistent with original perf probe. After all, we can use
>>>>> pt_regs directly or relay to perf-probe cache by Masami to deal
>>>>> with non-debug cases.
>>>>
>>>> so you're saying you don't want to support non-debug case for now?
>>>> Sure, as long as section name parser will be able to support
>>>> 'func(long, char) asmlinkage' syntax in the future without breaking
>>>> compatibility. I'm mostly interested in cases when debug info
>>>> is not available at all. So perf-probe cache is of no use to me.
>>>>
>>>>
>>>
>>> Yes, that syntax do deal with the situation which current 'perf
>>> probe' syntax not covered, so not only bpf prologue would benifit
>>> from that, maybe we could try to let perf probe involve that.
>>
>> Hmm, then how about below syntax?
>>
>>   perf probe x86_acpi_enter_sleep_state $regparams:asmlinkage(char)
>>
>> So, regparams has following synopsis.
>>
>>   $regparams[:[asmlinkage|0-6]([u8|u16|u32|u64|ptr][,...])]
> 
> the number doesn't make sense in generic command. Only x86_32 plays
> with calling convention. All other archs are not doing anything special
> for asmlinkage.

Yes, asmlinkage is a kernel hack. However, perf probe is not only for
kprobes, but also uprobes. So someone may want to use it.
Fortunately, perf probe itself can recognize it is kernel or not,
so only if the probe point is on the kernel, asmlinkage will work
as expected.

> I think the following is enough:
> $regparams[[:asmlinkage]([u8|u16|u32|u64|ptr|char|short|long|
> long long|void*][,...])]
> asmlinkage most of the time won't be used and typical command will look
> like: 'func=func $regparams(char, long, void*)'
> which is ok for kprobe.
> For bpf section name I would still prefer 'func(char, long, void*)'
> since it's more concise, easier to remember, more similar to C declaration.

Ah, that's interesting. I think perf probe can also use that :)

perf probe func(s8,ptr) $regparams (or $arg1 $arg2 ...)

Thank you!

>> Note that asmlinkage is a synonym of 0, and default depends on arch :)
>> Some architecture ignores this part, e.g. x86_64 always uses regs.
>> And it is automatically expanded to argX="%reg or $stackX".
>>
>> e.g.
>>   $regparams is expanded to
>>    arg1=%di arg2=%si arg3=%dx arg4=%cx arg5=%r8 arg6=%r9 (on x86_64)
>>    arg1=%ax arg2=%dx arg3=%cx arg4=$stack1 arg5=$stack2 arg6=$stack3 (on i386)
>>
>>   $regparams:0 is expanded to
>>    arg1=%di arg2=%si arg3=%dx arg4=%cx arg5=%r8 arg6=%r9 (on x86_64)
>>    arg1=$stack1 arg2=$stack2 arg3=$stack3 arg4=$stack4 arg5=$stack5 arg6=$stack6 (on i386)
>>
>>   $regparams:3(char,long) is expanded to
>>    arg1=%di:s8 arg2=%si:s64 (on x86_64)
>>    arg1=%ax:s8 arg2=%dx:s64 (on i386)
>>
>> How is this?
>>
>> Thank you,
>>
>>
> 
> 


-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

end of thread, other threads:[~2015-05-30  7:01 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-24  8:27 [RFC PATCH v2 00/15] perf bpf: Probing with local variable He Kuang
2015-05-24  8:27 ` [RFC PATCH v2 01/15] perf tools: Add lib/bpf to cscope target list He Kuang
2015-05-24  8:27 ` [RFC PATCH v2 02/15] perf bpf: Support custom vmlinux path He Kuang
2015-05-24  8:27 ` [RFC PATCH v2 03/15] perf bpf: Save pt_regs info from debuginfo He Kuang
2015-05-24 13:31   ` Masami Hiramatsu
2015-05-25  7:38     ` He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 04/15] perf tools: Add functions to get calling regs He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 05/15] perf tools: Add pt_regs offsets and calling regs for x86 He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 06/15] bpf tools: Add headers for generating bpf bytecode He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 07/15] bpf tools: Convert arglist to bpf prologue He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 08/15] bpf tools: Fetch calling regs to bpf arglist He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo He Kuang
2015-05-24  8:49   ` Masami Hiramatsu
2015-05-25  8:33     ` He Kuang
2015-05-25 12:22       ` Masami Hiramatsu
2015-05-25 12:46         ` Arnaldo Carvalho de Melo
2015-05-25 13:06           ` Masami Hiramatsu
2015-05-26 17:50       ` Alexei Starovoitov
2015-05-27  2:27         ` He Kuang
2015-05-27 11:43           ` Masami Hiramatsu
2015-05-27 15:30           ` Alexei Starovoitov
2015-05-28 13:01             ` He Kuang
2015-05-28 18:10               ` Alexei Starovoitov
2015-05-29  6:30                 ` He Kuang
2015-05-29 23:55                   ` Masami Hiramatsu
2015-05-30  1:27                     ` Alexei Starovoitov
2015-05-30  7:01                       ` Masami Hiramatsu
2015-05-24  8:28 ` [RFC PATCH v2 10/15] perf bpf: Process debuginfo for generating bpf prologue He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 11/15] perf bpf: Synthesize vars to generate " He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 12/15] perf bpf: Generate bpf prologue without debuginfo He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 13/15] perf bpf: Combine bpf prologue and bpf prog He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 14/15] samples/bpf: Add sample for testing bpf fetch args He Kuang
2015-05-24  8:28 ` [RFC PATCH v2 15/15] samples/bpf: Add sample for no-debuginfo case He Kuang
2015-05-26 17:53   ` Alexei Starovoitov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).