All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints
@ 2016-07-13 10:44 Wang Nan
  2016-07-13 10:44 ` [PATCH 1/5] tools lib bpf: New API to adjust type of a BPF program Wang Nan
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Wang Nan @ 2016-07-13 10:44 UTC (permalink / raw)
  To: acme
  Cc: lizefan, linux-kernel, pi3orama, Wang Nan,
	Arnaldo Carvalho de Melo, Alexei Starovoitov, Jiri Olsa

This patch set allows BPF program attach to tracepoints, which is
supported by commit 98b5c2c65c29 ("perf, bpf: allow bpf programs
attach to tracepoints").

Wang Nan (5):
  tools lib bpf: New API to adjust type of a BPF program
  tools lib bpf: Report error when kernel doesn't support program type
  perf tools: event parser: Add const qualifier to evt_name and sys_name
  perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event()
  perf bpf: Support BPF program attach to tracepoints

 tools/lib/bpf/libbpf.c         | 80 ++++++++++++++++++++++++++++++++++--------
 tools/lib/bpf/libbpf.h         | 10 ++++++
 tools/perf/util/bpf-loader.c   | 73 +++++++++++++++++++++++++++++++++-----
 tools/perf/util/bpf-loader.h   | 12 +++----
 tools/perf/util/parse-events.c | 28 +++++++--------
 tools/perf/util/parse-events.h |  2 +-
 6 files changed, 161 insertions(+), 44 deletions(-)

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
-- 
1.8.3.4

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

* [PATCH 1/5] tools lib bpf: New API to adjust type of a BPF program
  2016-07-13 10:44 [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints Wang Nan
@ 2016-07-13 10:44 ` Wang Nan
  2016-07-14  7:02   ` [tip:perf/core] " tip-bot for Wang Nan
  2016-07-13 10:44 ` [PATCH 2/5] tools lib bpf: Report error when kernel doesn't support program type Wang Nan
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Wang Nan @ 2016-07-13 10:44 UTC (permalink / raw)
  To: acme
  Cc: lizefan, linux-kernel, pi3orama, Wang Nan,
	Arnaldo Carvalho de Melo, Alexei Starovoitov, Jiri Olsa

Add 4 new APIs to adjust and query the type of a BPF program.
Load program according to type set by caller. Default is set to
BPF_PROG_TYPE_KPROBE.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 tools/lib/bpf/libbpf.c | 53 +++++++++++++++++++++++++++++++++++++++++++-------
 tools/lib/bpf/libbpf.h |  9 +++++++++
 2 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 3dcda9e..4751936 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -158,6 +158,7 @@ struct bpf_program {
 	char *section_name;
 	struct bpf_insn *insns;
 	size_t insns_cnt;
+	enum bpf_prog_type type;
 
 	struct {
 		int insn_idx;
@@ -299,6 +300,7 @@ bpf_program__init(void *data, size_t size, char *name, int idx,
 	prog->idx = idx;
 	prog->instances.fds = NULL;
 	prog->instances.nr = -1;
+	prog->type = BPF_PROG_TYPE_KPROBE;
 
 	return 0;
 errout:
@@ -894,8 +896,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
 }
 
 static int
-load_program(struct bpf_insn *insns, int insns_cnt,
-	     char *license, u32 kern_version, int *pfd)
+load_program(enum bpf_prog_type type, struct bpf_insn *insns,
+	     int insns_cnt, char *license, u32 kern_version, int *pfd)
 {
 	int ret;
 	char *log_buf;
@@ -907,9 +909,8 @@ load_program(struct bpf_insn *insns, int insns_cnt,
 	if (!log_buf)
 		pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
 
-	ret = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
-			       insns_cnt, license, kern_version,
-			       log_buf, BPF_LOG_BUF_SIZE);
+	ret = bpf_load_program(type, insns, insns_cnt, license,
+			       kern_version, log_buf, BPF_LOG_BUF_SIZE);
 
 	if (ret >= 0) {
 		*pfd = ret;
@@ -968,7 +969,7 @@ bpf_program__load(struct bpf_program *prog,
 			pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
 				   prog->section_name, prog->instances.nr);
 		}
-		err = load_program(prog->insns, prog->insns_cnt,
+		err = load_program(prog->type, prog->insns, prog->insns_cnt,
 				   license, kern_version, &fd);
 		if (!err)
 			prog->instances.fds[0] = fd;
@@ -997,7 +998,7 @@ bpf_program__load(struct bpf_program *prog,
 			continue;
 		}
 
-		err = load_program(result.new_insn_ptr,
+		err = load_program(prog->type, result.new_insn_ptr,
 				   result.new_insn_cnt,
 				   license, kern_version, &fd);
 
@@ -1316,6 +1317,44 @@ int bpf_program__nth_fd(struct bpf_program *prog, int n)
 	return fd;
 }
 
+static void bpf_program__set_type(struct bpf_program *prog,
+				  enum bpf_prog_type type)
+{
+	prog->type = type;
+}
+
+int bpf_program__set_tracepoint(struct bpf_program *prog)
+{
+	if (!prog)
+		return -EINVAL;
+	bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
+	return 0;
+}
+
+int bpf_program__set_kprobe(struct bpf_program *prog)
+{
+	if (!prog)
+		return -EINVAL;
+	bpf_program__set_type(prog, BPF_PROG_TYPE_KPROBE);
+	return 0;
+}
+
+static bool bpf_program__is_type(struct bpf_program *prog,
+				 enum bpf_prog_type type)
+{
+	return prog ? (prog->type == type) : false;
+}
+
+bool bpf_program__is_tracepoint(struct bpf_program *prog)
+{
+	return bpf_program__is_type(prog, BPF_PROG_TYPE_TRACEPOINT);
+}
+
+bool bpf_program__is_kprobe(struct bpf_program *prog)
+{
+	return bpf_program__is_type(prog, BPF_PROG_TYPE_KPROBE);
+}
+
 int bpf_map__fd(struct bpf_map *map)
 {
 	return map ? map->fd : -EINVAL;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index f392c5e..eb2a4c4 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -165,6 +165,15 @@ int bpf_program__set_prep(struct bpf_program *prog, int nr_instance,
 int bpf_program__nth_fd(struct bpf_program *prog, int n);
 
 /*
+ * Adjust type of bpf program. Default is kprobe.
+ */
+int bpf_program__set_tracepoint(struct bpf_program *prog);
+int bpf_program__set_kprobe(struct bpf_program *prog);
+
+bool bpf_program__is_tracepoint(struct bpf_program *prog);
+bool bpf_program__is_kprobe(struct bpf_program *prog);
+
+/*
  * We don't need __attribute__((packed)) now since it is
  * unnecessary for 'bpf_map_def' because they are all aligned.
  * In addition, using it will trigger -Wpacked warning message,
-- 
1.8.3.4

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

* [PATCH 2/5] tools lib bpf: Report error when kernel doesn't support program type
  2016-07-13 10:44 [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints Wang Nan
  2016-07-13 10:44 ` [PATCH 1/5] tools lib bpf: New API to adjust type of a BPF program Wang Nan
@ 2016-07-13 10:44 ` Wang Nan
  2016-07-14  7:03   ` [tip:perf/core] " tip-bot for Wang Nan
  2016-07-13 10:44 ` [PATCH 3/5] perf tools: event parser: Add const qualifier to evt_name and sys_name Wang Nan
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Wang Nan @ 2016-07-13 10:44 UTC (permalink / raw)
  To: acme
  Cc: lizefan, linux-kernel, pi3orama, Wang Nan,
	Arnaldo Carvalho de Melo, Alexei Starovoitov, Jiri Olsa

Now libbpf support tracepoint program type. Report meanful error when
kernel version less than 4.7.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 tools/lib/bpf/libbpf.c | 27 ++++++++++++++++++++-------
 tools/lib/bpf/libbpf.h |  1 +
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 4751936..32e6b6b 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -90,6 +90,7 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
 	[ERRCODE_OFFSET(VERIFY)]	= "Kernel verifier blocks program loading",
 	[ERRCODE_OFFSET(PROG2BIG)]	= "Program too big",
 	[ERRCODE_OFFSET(KVER)]		= "Incorrect kernel version",
+	[ERRCODE_OFFSET(PROGTYPE)]	= "Kernel doesn't support this program type",
 };
 
 int libbpf_strerror(int err, char *buf, size_t size)
@@ -926,15 +927,27 @@ load_program(enum bpf_prog_type type, struct bpf_insn *insns,
 		pr_warning("-- BEGIN DUMP LOG ---\n");
 		pr_warning("\n%s\n", log_buf);
 		pr_warning("-- END LOG --\n");
+	} else if (insns_cnt >= BPF_MAXINSNS) {
+		pr_warning("Program too large (%d insns), at most %d insns\n",
+			   insns_cnt, BPF_MAXINSNS);
+		ret = -LIBBPF_ERRNO__PROG2BIG;
 	} else {
-		if (insns_cnt >= BPF_MAXINSNS) {
-			pr_warning("Program too large (%d insns), at most %d insns\n",
-				   insns_cnt, BPF_MAXINSNS);
-			ret = -LIBBPF_ERRNO__PROG2BIG;
-		} else if (log_buf) {
-			pr_warning("log buffer is empty\n");
-			ret = -LIBBPF_ERRNO__KVER;
+		/* Wrong program type? */
+		if (type != BPF_PROG_TYPE_KPROBE) {
+			int fd;
+
+			fd = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
+					      insns_cnt, license, kern_version,
+					      NULL, 0);
+			if (fd >= 0) {
+				close(fd);
+				ret = -LIBBPF_ERRNO__PROGTYPE;
+				goto out;
+			}
 		}
+
+		if (log_buf)
+			ret = -LIBBPF_ERRNO__KVER;
 	}
 
 out:
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index eb2a4c4..dd7a513 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -39,6 +39,7 @@ enum libbpf_errno {
 	LIBBPF_ERRNO__VERIFY,	/* Kernel verifier blocks program loading */
 	LIBBPF_ERRNO__PROG2BIG,	/* Program too big */
 	LIBBPF_ERRNO__KVER,	/* Incorrect kernel version */
+	LIBBPF_ERRNO__PROGTYPE,	/* Kernel doesn't support this program type */
 	__LIBBPF_ERRNO__END,
 };
 
-- 
1.8.3.4

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

* [PATCH 3/5] perf tools: event parser: Add const qualifier to evt_name and sys_name
  2016-07-13 10:44 [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints Wang Nan
  2016-07-13 10:44 ` [PATCH 1/5] tools lib bpf: New API to adjust type of a BPF program Wang Nan
  2016-07-13 10:44 ` [PATCH 2/5] tools lib bpf: Report error when kernel doesn't support program type Wang Nan
@ 2016-07-13 10:44 ` Wang Nan
  2016-07-14  7:03   ` [tip:perf/core] perf " tip-bot for Wang Nan
  2016-07-13 10:44 ` [PATCH 4/5] perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event() Wang Nan
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Wang Nan @ 2016-07-13 10:44 UTC (permalink / raw)
  To: acme
  Cc: lizefan, linux-kernel, pi3orama, Wang Nan,
	Arnaldo Carvalho de Melo, Alexei Starovoitov, Jiri Olsa

Add missing 'const' qualifiers so following commits are able to create
tracepoints using const strings.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/parse-events.c | 12 ++++++------
 tools/perf/util/parse-events.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index ebd87b7..d866824 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -436,7 +436,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,
 }
 
 static void tracepoint_error(struct parse_events_error *e, int err,
-			     char *sys, char *name)
+			     const char *sys, const char *name)
 {
 	char help[BUFSIZ];
 
@@ -466,7 +466,7 @@ static void tracepoint_error(struct parse_events_error *e, int err,
 }
 
 static int add_tracepoint(struct list_head *list, int *idx,
-			  char *sys_name, char *evt_name,
+			  const char *sys_name, const char *evt_name,
 			  struct parse_events_error *err,
 			  struct list_head *head_config)
 {
@@ -491,7 +491,7 @@ static int add_tracepoint(struct list_head *list, int *idx,
 }
 
 static int add_tracepoint_multi_event(struct list_head *list, int *idx,
-				      char *sys_name, char *evt_name,
+				      const char *sys_name, const char *evt_name,
 				      struct parse_events_error *err,
 				      struct list_head *head_config)
 {
@@ -533,7 +533,7 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
 }
 
 static int add_tracepoint_event(struct list_head *list, int *idx,
-				char *sys_name, char *evt_name,
+				const char *sys_name, const char *evt_name,
 				struct parse_events_error *err,
 				struct list_head *head_config)
 {
@@ -545,7 +545,7 @@ static int add_tracepoint_event(struct list_head *list, int *idx,
 }
 
 static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
-				    char *sys_name, char *evt_name,
+				    const char *sys_name, const char *evt_name,
 				    struct parse_events_error *err,
 				    struct list_head *head_config)
 {
@@ -1126,7 +1126,7 @@ do {								\
 }
 
 int parse_events_add_tracepoint(struct list_head *list, int *idx,
-				char *sys, char *event,
+				const char *sys, const char *event,
 				struct parse_events_error *err,
 				struct list_head *head_config)
 {
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 46c05cc..0bd664d 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -134,7 +134,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add);
 int parse_events__modifier_group(struct list_head *list, char *event_mod);
 int parse_events_name(struct list_head *list, char *name);
 int parse_events_add_tracepoint(struct list_head *list, int *idx,
-				char *sys, char *event,
+				const char *sys, const char *event,
 				struct parse_events_error *error,
 				struct list_head *head_config);
 int parse_events_load_bpf(struct parse_events_evlist *data,
-- 
1.8.3.4

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

* [PATCH 4/5] perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event()
  2016-07-13 10:44 [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints Wang Nan
                   ` (2 preceding siblings ...)
  2016-07-13 10:44 ` [PATCH 3/5] perf tools: event parser: Add const qualifier to evt_name and sys_name Wang Nan
@ 2016-07-13 10:44 ` Wang Nan
  2016-07-14  7:04   ` [tip:perf/core] " tip-bot for Wang Nan
  2016-07-13 10:44 ` [PATCH 5/5] perf bpf: Support BPF program attach to tracepoints Wang Nan
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Wang Nan @ 2016-07-13 10:44 UTC (permalink / raw)
  To: acme
  Cc: lizefan, linux-kernel, pi3orama, Wang Nan,
	Arnaldo Carvalho de Melo, Alexei Starovoitov, Jiri Olsa

Following commit will allow BPF script attach to tracepoints.
bpf__foreach_tev() will iterate over all events, not only kprobes.
Rename it to bpf__foreach_event().

Since only group and event are used by caller, there's no need to pass
full 'struct probe_trace_event' to bpf_prog_iter_callback_t. Pass only
these two strings. After this patch bpf_prog_iter_callback_t natually
support tracepoints.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/bpf-loader.c   |  8 ++++----
 tools/perf/util/bpf-loader.h   | 12 ++++++------
 tools/perf/util/parse-events.c | 16 ++++++++--------
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 8445e89..f227014 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -693,9 +693,9 @@ int bpf__load(struct bpf_object *obj)
 	return 0;
 }
 
-int bpf__foreach_tev(struct bpf_object *obj,
-		     bpf_prog_iter_callback_t func,
-		     void *arg)
+int bpf__foreach_event(struct bpf_object *obj,
+		       bpf_prog_iter_callback_t func,
+		       void *arg)
 {
 	struct bpf_program *prog;
 	int err;
@@ -728,7 +728,7 @@ int bpf__foreach_tev(struct bpf_object *obj,
 				return fd;
 			}
 
-			err = (*func)(tev, fd, arg);
+			err = (*func)(tev->group, tev->event, fd, arg);
 			if (err) {
 				pr_debug("bpf: call back failed, stop iterate\n");
 				return err;
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 941e172..f2b737b 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -46,7 +46,7 @@ struct bpf_object;
 struct parse_events_term;
 #define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
 
-typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev,
+typedef int (*bpf_prog_iter_callback_t)(const char *group, const char *event,
 					int fd, void *arg);
 
 #ifdef HAVE_LIBBPF_SUPPORT
@@ -67,8 +67,8 @@ int bpf__strerror_probe(struct bpf_object *obj, int err,
 int bpf__load(struct bpf_object *obj);
 int bpf__strerror_load(struct bpf_object *obj, int err,
 		       char *buf, size_t size);
-int bpf__foreach_tev(struct bpf_object *obj,
-		     bpf_prog_iter_callback_t func, void *arg);
+int bpf__foreach_event(struct bpf_object *obj,
+		       bpf_prog_iter_callback_t func, void *arg);
 
 int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term,
 		    struct perf_evlist *evlist, int *error_pos);
@@ -107,9 +107,9 @@ static inline int bpf__unprobe(struct bpf_object *obj __maybe_unused) { return 0
 static inline int bpf__load(struct bpf_object *obj __maybe_unused) { return 0; }
 
 static inline int
-bpf__foreach_tev(struct bpf_object *obj __maybe_unused,
-		 bpf_prog_iter_callback_t func __maybe_unused,
-		 void *arg __maybe_unused)
+bpf__foreach_event(struct bpf_object *obj __maybe_unused,
+		   bpf_prog_iter_callback_t func __maybe_unused,
+		   void *arg __maybe_unused)
 {
 	return 0;
 }
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d866824..6b4fff3 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -584,7 +584,7 @@ struct __add_bpf_event_param {
 	struct list_head *head_config;
 };
 
-static int add_bpf_event(struct probe_trace_event *tev, int fd,
+static int add_bpf_event(const char *group, const char *event, int fd,
 			 void *_param)
 {
 	LIST_HEAD(new_evsels);
@@ -595,27 +595,27 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd,
 	int err;
 
 	pr_debug("add bpf event %s:%s and attach bpf program %d\n",
-		 tev->group, tev->event, fd);
+		 group, event, fd);
 
-	err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, tev->group,
-					  tev->event, evlist->error,
+	err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, group,
+					  event, evlist->error,
 					  param->head_config);
 	if (err) {
 		struct perf_evsel *evsel, *tmp;
 
 		pr_debug("Failed to add BPF event %s:%s\n",
-			 tev->group, tev->event);
+			 group, event);
 		list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
 			list_del(&evsel->node);
 			perf_evsel__delete(evsel);
 		}
 		return err;
 	}
-	pr_debug("adding %s:%s\n", tev->group, tev->event);
+	pr_debug("adding %s:%s\n", group, event);
 
 	list_for_each_entry(pos, &new_evsels, node) {
 		pr_debug("adding %s:%s to %p\n",
-			 tev->group, tev->event, pos);
+			 group, event, pos);
 		pos->bpf_fd = fd;
 	}
 	list_splice(&new_evsels, list);
@@ -661,7 +661,7 @@ int parse_events_load_bpf_obj(struct parse_events_evlist *data,
 		goto errout;
 	}
 
-	err = bpf__foreach_tev(obj, add_bpf_event, &param);
+	err = bpf__foreach_event(obj, add_bpf_event, &param);
 	if (err) {
 		snprintf(errbuf, sizeof(errbuf),
 			 "Attach events in BPF object failed");
-- 
1.8.3.4

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

* [PATCH 5/5] perf bpf: Support BPF program attach to tracepoints
  2016-07-13 10:44 [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints Wang Nan
                   ` (3 preceding siblings ...)
  2016-07-13 10:44 ` [PATCH 4/5] perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event() Wang Nan
@ 2016-07-13 10:44 ` Wang Nan
  2016-07-14  7:04   ` [tip:perf/core] " tip-bot for Wang Nan
  2016-07-13 10:44 ` [PATCH 5/5] " Wang Nan
  2016-07-13 18:56 ` [PATCH 0/5] perf bpf: Allow BPF programs " Arnaldo Carvalho de Melo
  6 siblings, 1 reply; 13+ messages in thread
From: Wang Nan @ 2016-07-13 10:44 UTC (permalink / raw)
  To: acme
  Cc: lizefan, linux-kernel, pi3orama, Wang Nan,
	Arnaldo Carvalho de Melo, Alexei Starovoitov, Jiri Olsa

To support commit 98b5c2c65c29 ("perf, bpf: allow bpf
programs attach to tracepoints"), this patch allows BPF script select
tracepoints in their section name.

Example:

 # cat test_tracepoint.c
 /*********************************************/
 #include <uapi/linux/bpf.h>
 #define SEC(NAME) __attribute__((section(NAME), used))
 SEC("raw_syscalls:sys_enter")
 int func(void *ctx)
 {
 	/*
 	 * /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/format:
 	 * ...
 	 * field:long id;	offset:8;	size:8;	signed:1;
 	 * ...
 	 * ctx + 8 select 'id'
 	 */
 	u64 id = *((u64 *)(ctx + 8));
 	if (id == 1)
 		return 1;
 	return 0;
 }
 SEC("_write=sys_write")
 int _write(void *ctx)
 {
 	return 1;
 }
 char _license[] SEC("license") = "GPL";
 int _version SEC("version") = LINUX_VERSION_CODE;
 /*********************************************/
 # perf record -e ./test_tracepoint.c  dd if=/dev/zero of=/dev/null count=5
 5+0 records in
 5+0 records out
 2560 bytes (2.6 kB) copied, 6.2281e-05 s, 41.1 MB/s
 [ perf record: Woken up 1 times to write data ]
 # perf script
              dd 13436 [005]  1596.490869: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, 7ffe82470d60, ffffffffffffe020, fffff
              dd 13436 [005]  1596.490871:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490873: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
              dd 13436 [005]  1596.490874:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490876: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
              dd 13436 [005]  1596.490876:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490878: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
              dd 13436 [005]  1596.490879:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490881: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
              dd 13436 [005]  1596.490882:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490900: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1f, 40acb8, 7f44bac74700, 7f44baa4fba
              dd 13436 [005]  1596.490901:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490917: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1a, fffffffa, 7f44bac74700, 7f44baa4f
              dd 13436 [005]  1596.490918:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490932: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1a, fffffff9, 7f44bac74700, 7f44baa4f
              dd 13436 [005]  1596.490933:  perf_bpf_probe:_write: (ffffffff812351e0)

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/bpf-loader.c | 65 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index f227014..1f12e4e 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -37,6 +37,9 @@ DEFINE_PRINT_FN(info, 1)
 DEFINE_PRINT_FN(debug, 1)
 
 struct bpf_prog_priv {
+	bool is_tp;
+	char *sys_name;
+	char *evt_name;
 	struct perf_probe_event pev;
 	bool need_prologue;
 	struct bpf_insn *insns_buf;
@@ -118,6 +121,8 @@ clear_prog_priv(struct bpf_program *prog __maybe_unused,
 	cleanup_perf_probe_events(&priv->pev, 1);
 	zfree(&priv->insns_buf);
 	zfree(&priv->type_mapping);
+	zfree(&priv->sys_name);
+	zfree(&priv->evt_name);
 	free(priv);
 }
 
@@ -269,7 +274,8 @@ nextline:
 }
 
 static int
-parse_prog_config(const char *config_str, struct perf_probe_event *pev)
+parse_prog_config(const char *config_str, const char **p_main_str,
+		  bool *is_tp, struct perf_probe_event *pev)
 {
 	int err;
 	const char *main_str = parse_prog_config_kvpair(config_str, pev);
@@ -277,6 +283,22 @@ parse_prog_config(const char *config_str, struct perf_probe_event *pev)
 	if (IS_ERR(main_str))
 		return PTR_ERR(main_str);
 
+	*p_main_str = main_str;
+	if (!strchr(main_str, '=')) {
+		/* Is a tracepoint event? */
+		const char *s = strchr(main_str, ':');
+
+		if (!s) {
+			pr_debug("bpf: '%s' is not a valid tracepoint\n",
+				 config_str);
+			return -BPF_LOADER_ERRNO__CONFIG;
+		}
+
+		*is_tp = true;
+		return 0;
+	}
+
+	*is_tp = false;
 	err = parse_perf_probe_command(main_str, pev);
 	if (err < 0) {
 		pr_debug("bpf: '%s' is not a valid config string\n",
@@ -292,7 +314,8 @@ config_bpf_program(struct bpf_program *prog)
 {
 	struct perf_probe_event *pev = NULL;
 	struct bpf_prog_priv *priv = NULL;
-	const char *config_str;
+	const char *config_str, *main_str;
+	bool is_tp = false;
 	int err;
 
 	/* Initialize per-program probing setting */
@@ -313,10 +336,19 @@ config_bpf_program(struct bpf_program *prog)
 	pev = &priv->pev;
 
 	pr_debug("bpf: config program '%s'\n", config_str);
-	err = parse_prog_config(config_str, pev);
+	err = parse_prog_config(config_str, &main_str, &is_tp, pev);
 	if (err)
 		goto errout;
 
+	if (is_tp) {
+		char *s = strchr(main_str, ':');
+
+		priv->is_tp = true;
+		priv->sys_name = strndup(main_str, s - main_str);
+		priv->evt_name = strdup(s + 1);
+		goto set_priv;
+	}
+
 	if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
 		pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
 			 config_str, PERF_BPF_PROBE_GROUP);
@@ -339,6 +371,7 @@ config_bpf_program(struct bpf_program *prog)
 	}
 	pr_debug("bpf: config '%s' is ok\n", config_str);
 
+set_priv:
 	err = bpf_program__set_priv(prog, priv, clear_prog_priv);
 	if (err) {
 		pr_debug("Failed to set priv for program '%s'\n", config_str);
@@ -387,7 +420,7 @@ preproc_gen_prologue(struct bpf_program *prog, int n,
 	size_t prologue_cnt = 0;
 	int i, err;
 
-	if (IS_ERR(priv) || !priv)
+	if (IS_ERR(priv) || !priv || priv->is_tp)
 		goto errout;
 
 	pev = &priv->pev;
@@ -544,6 +577,11 @@ static int hook_load_preprocessor(struct bpf_program *prog)
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
 
+	if (priv->is_tp) {
+		priv->need_prologue = false;
+		return 0;
+	}
+
 	pev = &priv->pev;
 	for (i = 0; i < pev->ntevs; i++) {
 		struct probe_trace_event *tev = &pev->tevs[i];
@@ -610,6 +648,13 @@ int bpf__probe(struct bpf_object *obj)
 			err = PTR_ERR(priv);
 			goto out;
 		}
+
+		if (priv->is_tp) {
+			bpf_program__set_tracepoint(prog);
+			continue;
+		}
+
+		bpf_program__set_kprobe(prog);
 		pev = &priv->pev;
 
 		err = convert_perf_probe_events(pev, 1);
@@ -650,7 +695,7 @@ int bpf__unprobe(struct bpf_object *obj)
 		struct bpf_prog_priv *priv = bpf_program__priv(prog);
 		int i;
 
-		if (IS_ERR(priv) || !priv)
+		if (IS_ERR(priv) || !priv || priv->is_tp)
 			continue;
 
 		for (i = 0; i < priv->pev.ntevs; i++) {
@@ -711,6 +756,16 @@ int bpf__foreach_event(struct bpf_object *obj,
 			return -BPF_LOADER_ERRNO__INTERNAL;
 		}
 
+		if (priv->is_tp) {
+			fd = bpf_program__fd(prog);
+			err = (*func)(priv->sys_name, priv->evt_name, fd, arg);
+			if (err) {
+				pr_debug("bpf: tracepoint call back failed, stop iterate\n");
+				return err;
+			}
+			continue;
+		}
+
 		pev = &priv->pev;
 		for (i = 0; i < pev->ntevs; i++) {
 			tev = &pev->tevs[i];
-- 
1.8.3.4

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

* [PATCH 5/5] perf bpf: Support BPF program attach to tracepoints
  2016-07-13 10:44 [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints Wang Nan
                   ` (4 preceding siblings ...)
  2016-07-13 10:44 ` [PATCH 5/5] perf bpf: Support BPF program attach to tracepoints Wang Nan
@ 2016-07-13 10:44 ` Wang Nan
  2016-07-13 18:56 ` [PATCH 0/5] perf bpf: Allow BPF programs " Arnaldo Carvalho de Melo
  6 siblings, 0 replies; 13+ messages in thread
From: Wang Nan @ 2016-07-13 10:44 UTC (permalink / raw)
  To: acme
  Cc: lizefan, linux-kernel, pi3orama, Wang Nan,
	Arnaldo Carvalho de Melo, Alexei Starovoitov, Jiri Olsa

To support commit 98b5c2c65c29 ("perf, bpf: allow bpf
programs attach to tracepoints"), this patch allows BPF script select
tracepoints in their section name.

Example:

 # cat test_tracepoint.c
 /*********************************************/
 #include <uapi/linux/bpf.h>
 #define SEC(NAME) __attribute__((section(NAME), used))
 SEC("raw_syscalls:sys_enter")
 int func(void *ctx)
 {
 	/*
 	 * /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/format:
 	 * ...
 	 * field:long id;	offset:8;	size:8;	signed:1;
 	 * ...
 	 * ctx + 8 select 'id'
 	 */
 	u64 id = *((u64 *)(ctx + 8));
 	if (id == 1)
 		return 1;
 	return 0;
 }
 SEC("_write=sys_write")
 int _write(void *ctx)
 {
 	return 1;
 }
 char _license[] SEC("license") = "GPL";
 int _version SEC("version") = LINUX_VERSION_CODE;
 /*********************************************/
 # perf record -e ./test_tracepoint.c  dd if=/dev/zero of=/dev/null count=5
 5+0 records in
 5+0 records out
 2560 bytes (2.6 kB) copied, 6.2281e-05 s, 41.1 MB/s
 [ perf record: Woken up 1 times to write data ]
 # perf script
              dd 13436 [005]  1596.490869: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, 7ffe82470d60, ffffffffffffe020, fffff
              dd 13436 [005]  1596.490871:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490873: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
              dd 13436 [005]  1596.490874:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490876: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
              dd 13436 [005]  1596.490876:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490878: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
              dd 13436 [005]  1596.490879:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490881: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
              dd 13436 [005]  1596.490882:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490900: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1f, 40acb8, 7f44bac74700, 7f44baa4fba
              dd 13436 [005]  1596.490901:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490917: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1a, fffffffa, 7f44bac74700, 7f44baa4f
              dd 13436 [005]  1596.490918:  perf_bpf_probe:_write: (ffffffff812351e0)
              dd 13436 [005]  1596.490932: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1a, fffffff9, 7f44bac74700, 7f44baa4f
              dd 13436 [005]  1596.490933:  perf_bpf_probe:_write: (ffffffff812351e0)

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/bpf-loader.c | 65 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index f227014..1f12e4e 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -37,6 +37,9 @@ DEFINE_PRINT_FN(info, 1)
 DEFINE_PRINT_FN(debug, 1)
 
 struct bpf_prog_priv {
+	bool is_tp;
+	char *sys_name;
+	char *evt_name;
 	struct perf_probe_event pev;
 	bool need_prologue;
 	struct bpf_insn *insns_buf;
@@ -118,6 +121,8 @@ clear_prog_priv(struct bpf_program *prog __maybe_unused,
 	cleanup_perf_probe_events(&priv->pev, 1);
 	zfree(&priv->insns_buf);
 	zfree(&priv->type_mapping);
+	zfree(&priv->sys_name);
+	zfree(&priv->evt_name);
 	free(priv);
 }
 
@@ -269,7 +274,8 @@ nextline:
 }
 
 static int
-parse_prog_config(const char *config_str, struct perf_probe_event *pev)
+parse_prog_config(const char *config_str, const char **p_main_str,
+		  bool *is_tp, struct perf_probe_event *pev)
 {
 	int err;
 	const char *main_str = parse_prog_config_kvpair(config_str, pev);
@@ -277,6 +283,22 @@ parse_prog_config(const char *config_str, struct perf_probe_event *pev)
 	if (IS_ERR(main_str))
 		return PTR_ERR(main_str);
 
+	*p_main_str = main_str;
+	if (!strchr(main_str, '=')) {
+		/* Is a tracepoint event? */
+		const char *s = strchr(main_str, ':');
+
+		if (!s) {
+			pr_debug("bpf: '%s' is not a valid tracepoint\n",
+				 config_str);
+			return -BPF_LOADER_ERRNO__CONFIG;
+		}
+
+		*is_tp = true;
+		return 0;
+	}
+
+	*is_tp = false;
 	err = parse_perf_probe_command(main_str, pev);
 	if (err < 0) {
 		pr_debug("bpf: '%s' is not a valid config string\n",
@@ -292,7 +314,8 @@ config_bpf_program(struct bpf_program *prog)
 {
 	struct perf_probe_event *pev = NULL;
 	struct bpf_prog_priv *priv = NULL;
-	const char *config_str;
+	const char *config_str, *main_str;
+	bool is_tp = false;
 	int err;
 
 	/* Initialize per-program probing setting */
@@ -313,10 +336,19 @@ config_bpf_program(struct bpf_program *prog)
 	pev = &priv->pev;
 
 	pr_debug("bpf: config program '%s'\n", config_str);
-	err = parse_prog_config(config_str, pev);
+	err = parse_prog_config(config_str, &main_str, &is_tp, pev);
 	if (err)
 		goto errout;
 
+	if (is_tp) {
+		char *s = strchr(main_str, ':');
+
+		priv->is_tp = true;
+		priv->sys_name = strndup(main_str, s - main_str);
+		priv->evt_name = strdup(s + 1);
+		goto set_priv;
+	}
+
 	if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
 		pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
 			 config_str, PERF_BPF_PROBE_GROUP);
@@ -339,6 +371,7 @@ config_bpf_program(struct bpf_program *prog)
 	}
 	pr_debug("bpf: config '%s' is ok\n", config_str);
 
+set_priv:
 	err = bpf_program__set_priv(prog, priv, clear_prog_priv);
 	if (err) {
 		pr_debug("Failed to set priv for program '%s'\n", config_str);
@@ -387,7 +420,7 @@ preproc_gen_prologue(struct bpf_program *prog, int n,
 	size_t prologue_cnt = 0;
 	int i, err;
 
-	if (IS_ERR(priv) || !priv)
+	if (IS_ERR(priv) || !priv || priv->is_tp)
 		goto errout;
 
 	pev = &priv->pev;
@@ -544,6 +577,11 @@ static int hook_load_preprocessor(struct bpf_program *prog)
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
 
+	if (priv->is_tp) {
+		priv->need_prologue = false;
+		return 0;
+	}
+
 	pev = &priv->pev;
 	for (i = 0; i < pev->ntevs; i++) {
 		struct probe_trace_event *tev = &pev->tevs[i];
@@ -610,6 +648,13 @@ int bpf__probe(struct bpf_object *obj)
 			err = PTR_ERR(priv);
 			goto out;
 		}
+
+		if (priv->is_tp) {
+			bpf_program__set_tracepoint(prog);
+			continue;
+		}
+
+		bpf_program__set_kprobe(prog);
 		pev = &priv->pev;
 
 		err = convert_perf_probe_events(pev, 1);
@@ -650,7 +695,7 @@ int bpf__unprobe(struct bpf_object *obj)
 		struct bpf_prog_priv *priv = bpf_program__priv(prog);
 		int i;
 
-		if (IS_ERR(priv) || !priv)
+		if (IS_ERR(priv) || !priv || priv->is_tp)
 			continue;
 
 		for (i = 0; i < priv->pev.ntevs; i++) {
@@ -711,6 +756,16 @@ int bpf__foreach_event(struct bpf_object *obj,
 			return -BPF_LOADER_ERRNO__INTERNAL;
 		}
 
+		if (priv->is_tp) {
+			fd = bpf_program__fd(prog);
+			err = (*func)(priv->sys_name, priv->evt_name, fd, arg);
+			if (err) {
+				pr_debug("bpf: tracepoint call back failed, stop iterate\n");
+				return err;
+			}
+			continue;
+		}
+
 		pev = &priv->pev;
 		for (i = 0; i < pev->ntevs; i++) {
 			tev = &pev->tevs[i];
-- 
1.8.3.4

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

* Re: [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints
  2016-07-13 10:44 [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints Wang Nan
                   ` (5 preceding siblings ...)
  2016-07-13 10:44 ` [PATCH 5/5] " Wang Nan
@ 2016-07-13 18:56 ` Arnaldo Carvalho de Melo
  6 siblings, 0 replies; 13+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-13 18:56 UTC (permalink / raw)
  To: Wang Nan
  Cc: lizefan, linux-kernel, pi3orama, Arnaldo Carvalho de Melo,
	Alexei Starovoitov, Jiri Olsa

Em Wed, Jul 13, 2016 at 10:44:00AM +0000, Wang Nan escreveu:
> This patch set allows BPF program attach to tracepoints, which is
> supported by commit 98b5c2c65c29 ("perf, bpf: allow bpf programs
> attach to tracepoints").

Thanks, tested and applied,

- Arnaldo
 
> Wang Nan (5):
>   tools lib bpf: New API to adjust type of a BPF program
>   tools lib bpf: Report error when kernel doesn't support program type
>   perf tools: event parser: Add const qualifier to evt_name and sys_name
>   perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event()
>   perf bpf: Support BPF program attach to tracepoints
> 
>  tools/lib/bpf/libbpf.c         | 80 ++++++++++++++++++++++++++++++++++--------
>  tools/lib/bpf/libbpf.h         | 10 ++++++
>  tools/perf/util/bpf-loader.c   | 73 +++++++++++++++++++++++++++++++++-----
>  tools/perf/util/bpf-loader.h   | 12 +++----
>  tools/perf/util/parse-events.c | 28 +++++++--------
>  tools/perf/util/parse-events.h |  2 +-
>  6 files changed, 161 insertions(+), 44 deletions(-)
> 
> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Li Zefan <lizefan@huawei.com>
> Cc: Jiri Olsa <jolsa@kernel.org>
> -- 
> 1.8.3.4

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

* [tip:perf/core] tools lib bpf: New API to adjust type of a BPF program
  2016-07-13 10:44 ` [PATCH 1/5] tools lib bpf: New API to adjust type of a BPF program Wang Nan
@ 2016-07-14  7:02   ` tip-bot for Wang Nan
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Wang Nan @ 2016-07-14  7:02 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, ast, tglx, jolsa, acme, linux-kernel, hpa, lizefan,
	wangnan0

Commit-ID:  5f44e4c810bf3ace5a97a84554d4eeccbb563ca5
Gitweb:     http://git.kernel.org/tip/5f44e4c810bf3ace5a97a84554d4eeccbb563ca5
Author:     Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 13 Jul 2016 10:44:01 +0000
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:02 -0300

tools lib bpf: New API to adjust type of a BPF program

Add 4 new APIs to adjust and query the type of a BPF program.
Load program according to type set by caller. Default is set to
BPF_PROG_TYPE_KPROBE.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468406646-21642-2-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c | 53 +++++++++++++++++++++++++++++++++++++++++++-------
 tools/lib/bpf/libbpf.h |  9 +++++++++
 2 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 3dcda9e..4751936 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -158,6 +158,7 @@ struct bpf_program {
 	char *section_name;
 	struct bpf_insn *insns;
 	size_t insns_cnt;
+	enum bpf_prog_type type;
 
 	struct {
 		int insn_idx;
@@ -299,6 +300,7 @@ bpf_program__init(void *data, size_t size, char *name, int idx,
 	prog->idx = idx;
 	prog->instances.fds = NULL;
 	prog->instances.nr = -1;
+	prog->type = BPF_PROG_TYPE_KPROBE;
 
 	return 0;
 errout:
@@ -894,8 +896,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
 }
 
 static int
-load_program(struct bpf_insn *insns, int insns_cnt,
-	     char *license, u32 kern_version, int *pfd)
+load_program(enum bpf_prog_type type, struct bpf_insn *insns,
+	     int insns_cnt, char *license, u32 kern_version, int *pfd)
 {
 	int ret;
 	char *log_buf;
@@ -907,9 +909,8 @@ load_program(struct bpf_insn *insns, int insns_cnt,
 	if (!log_buf)
 		pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
 
-	ret = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
-			       insns_cnt, license, kern_version,
-			       log_buf, BPF_LOG_BUF_SIZE);
+	ret = bpf_load_program(type, insns, insns_cnt, license,
+			       kern_version, log_buf, BPF_LOG_BUF_SIZE);
 
 	if (ret >= 0) {
 		*pfd = ret;
@@ -968,7 +969,7 @@ bpf_program__load(struct bpf_program *prog,
 			pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
 				   prog->section_name, prog->instances.nr);
 		}
-		err = load_program(prog->insns, prog->insns_cnt,
+		err = load_program(prog->type, prog->insns, prog->insns_cnt,
 				   license, kern_version, &fd);
 		if (!err)
 			prog->instances.fds[0] = fd;
@@ -997,7 +998,7 @@ bpf_program__load(struct bpf_program *prog,
 			continue;
 		}
 
-		err = load_program(result.new_insn_ptr,
+		err = load_program(prog->type, result.new_insn_ptr,
 				   result.new_insn_cnt,
 				   license, kern_version, &fd);
 
@@ -1316,6 +1317,44 @@ int bpf_program__nth_fd(struct bpf_program *prog, int n)
 	return fd;
 }
 
+static void bpf_program__set_type(struct bpf_program *prog,
+				  enum bpf_prog_type type)
+{
+	prog->type = type;
+}
+
+int bpf_program__set_tracepoint(struct bpf_program *prog)
+{
+	if (!prog)
+		return -EINVAL;
+	bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
+	return 0;
+}
+
+int bpf_program__set_kprobe(struct bpf_program *prog)
+{
+	if (!prog)
+		return -EINVAL;
+	bpf_program__set_type(prog, BPF_PROG_TYPE_KPROBE);
+	return 0;
+}
+
+static bool bpf_program__is_type(struct bpf_program *prog,
+				 enum bpf_prog_type type)
+{
+	return prog ? (prog->type == type) : false;
+}
+
+bool bpf_program__is_tracepoint(struct bpf_program *prog)
+{
+	return bpf_program__is_type(prog, BPF_PROG_TYPE_TRACEPOINT);
+}
+
+bool bpf_program__is_kprobe(struct bpf_program *prog)
+{
+	return bpf_program__is_type(prog, BPF_PROG_TYPE_KPROBE);
+}
+
 int bpf_map__fd(struct bpf_map *map)
 {
 	return map ? map->fd : -EINVAL;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index f392c5e..eb2a4c4 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -165,6 +165,15 @@ int bpf_program__set_prep(struct bpf_program *prog, int nr_instance,
 int bpf_program__nth_fd(struct bpf_program *prog, int n);
 
 /*
+ * Adjust type of bpf program. Default is kprobe.
+ */
+int bpf_program__set_tracepoint(struct bpf_program *prog);
+int bpf_program__set_kprobe(struct bpf_program *prog);
+
+bool bpf_program__is_tracepoint(struct bpf_program *prog);
+bool bpf_program__is_kprobe(struct bpf_program *prog);
+
+/*
  * We don't need __attribute__((packed)) now since it is
  * unnecessary for 'bpf_map_def' because they are all aligned.
  * In addition, using it will trigger -Wpacked warning message,

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

* [tip:perf/core] tools lib bpf: Report error when kernel doesn't support program type
  2016-07-13 10:44 ` [PATCH 2/5] tools lib bpf: Report error when kernel doesn't support program type Wang Nan
@ 2016-07-14  7:03   ` tip-bot for Wang Nan
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Wang Nan @ 2016-07-14  7:03 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: wangnan0, lizefan, tglx, hpa, ast, jolsa, acme, linux-kernel,
	mingo

Commit-ID:  705fa2190dfb3d02f83adcd1abdb4e7dc3434597
Gitweb:     http://git.kernel.org/tip/705fa2190dfb3d02f83adcd1abdb4e7dc3434597
Author:     Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 13 Jul 2016 10:44:02 +0000
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:02 -0300

tools lib bpf: Report error when kernel doesn't support program type

Now libbpf support tracepoint program type. Report meaningful error when kernel
version is less than 4.7.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468406646-21642-3-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c | 27 ++++++++++++++++++++-------
 tools/lib/bpf/libbpf.h |  1 +
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 4751936..32e6b6b 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -90,6 +90,7 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
 	[ERRCODE_OFFSET(VERIFY)]	= "Kernel verifier blocks program loading",
 	[ERRCODE_OFFSET(PROG2BIG)]	= "Program too big",
 	[ERRCODE_OFFSET(KVER)]		= "Incorrect kernel version",
+	[ERRCODE_OFFSET(PROGTYPE)]	= "Kernel doesn't support this program type",
 };
 
 int libbpf_strerror(int err, char *buf, size_t size)
@@ -926,15 +927,27 @@ load_program(enum bpf_prog_type type, struct bpf_insn *insns,
 		pr_warning("-- BEGIN DUMP LOG ---\n");
 		pr_warning("\n%s\n", log_buf);
 		pr_warning("-- END LOG --\n");
+	} else if (insns_cnt >= BPF_MAXINSNS) {
+		pr_warning("Program too large (%d insns), at most %d insns\n",
+			   insns_cnt, BPF_MAXINSNS);
+		ret = -LIBBPF_ERRNO__PROG2BIG;
 	} else {
-		if (insns_cnt >= BPF_MAXINSNS) {
-			pr_warning("Program too large (%d insns), at most %d insns\n",
-				   insns_cnt, BPF_MAXINSNS);
-			ret = -LIBBPF_ERRNO__PROG2BIG;
-		} else if (log_buf) {
-			pr_warning("log buffer is empty\n");
-			ret = -LIBBPF_ERRNO__KVER;
+		/* Wrong program type? */
+		if (type != BPF_PROG_TYPE_KPROBE) {
+			int fd;
+
+			fd = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
+					      insns_cnt, license, kern_version,
+					      NULL, 0);
+			if (fd >= 0) {
+				close(fd);
+				ret = -LIBBPF_ERRNO__PROGTYPE;
+				goto out;
+			}
 		}
+
+		if (log_buf)
+			ret = -LIBBPF_ERRNO__KVER;
 	}
 
 out:
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index eb2a4c4..dd7a513 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -39,6 +39,7 @@ enum libbpf_errno {
 	LIBBPF_ERRNO__VERIFY,	/* Kernel verifier blocks program loading */
 	LIBBPF_ERRNO__PROG2BIG,	/* Program too big */
 	LIBBPF_ERRNO__KVER,	/* Incorrect kernel version */
+	LIBBPF_ERRNO__PROGTYPE,	/* Kernel doesn't support this program type */
 	__LIBBPF_ERRNO__END,
 };
 

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

* [tip:perf/core] perf event parser: Add const qualifier to evt_name and sys_name
  2016-07-13 10:44 ` [PATCH 3/5] perf tools: event parser: Add const qualifier to evt_name and sys_name Wang Nan
@ 2016-07-14  7:03   ` tip-bot for Wang Nan
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Wang Nan @ 2016-07-14  7:03 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, hpa, mingo, acme, linux-kernel, wangnan0, lizefan, jolsa,
	ast

Commit-ID:  8c619d6a333f98087816e64c62f0f2389e19ab4a
Gitweb:     http://git.kernel.org/tip/8c619d6a333f98087816e64c62f0f2389e19ab4a
Author:     Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 13 Jul 2016 10:44:03 +0000
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:03 -0300

perf event parser: Add const qualifier to evt_name and sys_name

Add missing 'const' qualifiers so following commits are able to create
tracepoints using const strings.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468406646-21642-4-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-events.c | 12 ++++++------
 tools/perf/util/parse-events.h |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index ebd87b7..d866824 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -436,7 +436,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,
 }
 
 static void tracepoint_error(struct parse_events_error *e, int err,
-			     char *sys, char *name)
+			     const char *sys, const char *name)
 {
 	char help[BUFSIZ];
 
@@ -466,7 +466,7 @@ static void tracepoint_error(struct parse_events_error *e, int err,
 }
 
 static int add_tracepoint(struct list_head *list, int *idx,
-			  char *sys_name, char *evt_name,
+			  const char *sys_name, const char *evt_name,
 			  struct parse_events_error *err,
 			  struct list_head *head_config)
 {
@@ -491,7 +491,7 @@ static int add_tracepoint(struct list_head *list, int *idx,
 }
 
 static int add_tracepoint_multi_event(struct list_head *list, int *idx,
-				      char *sys_name, char *evt_name,
+				      const char *sys_name, const char *evt_name,
 				      struct parse_events_error *err,
 				      struct list_head *head_config)
 {
@@ -533,7 +533,7 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
 }
 
 static int add_tracepoint_event(struct list_head *list, int *idx,
-				char *sys_name, char *evt_name,
+				const char *sys_name, const char *evt_name,
 				struct parse_events_error *err,
 				struct list_head *head_config)
 {
@@ -545,7 +545,7 @@ static int add_tracepoint_event(struct list_head *list, int *idx,
 }
 
 static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
-				    char *sys_name, char *evt_name,
+				    const char *sys_name, const char *evt_name,
 				    struct parse_events_error *err,
 				    struct list_head *head_config)
 {
@@ -1126,7 +1126,7 @@ do {								\
 }
 
 int parse_events_add_tracepoint(struct list_head *list, int *idx,
-				char *sys, char *event,
+				const char *sys, const char *event,
 				struct parse_events_error *err,
 				struct list_head *head_config)
 {
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 46c05cc..0bd664d 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -134,7 +134,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add);
 int parse_events__modifier_group(struct list_head *list, char *event_mod);
 int parse_events_name(struct list_head *list, char *name);
 int parse_events_add_tracepoint(struct list_head *list, int *idx,
-				char *sys, char *event,
+				const char *sys, const char *event,
 				struct parse_events_error *error,
 				struct list_head *head_config);
 int parse_events_load_bpf(struct parse_events_evlist *data,

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

* [tip:perf/core] perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event()
  2016-07-13 10:44 ` [PATCH 4/5] perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event() Wang Nan
@ 2016-07-14  7:04   ` tip-bot for Wang Nan
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Wang Nan @ 2016-07-14  7:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ast, linux-kernel, acme, jolsa, hpa, lizefan, wangnan0, tglx,
	mingo

Commit-ID:  cd102d70fe957b060b9df6bc4f54684de3fe00cd
Gitweb:     http://git.kernel.org/tip/cd102d70fe957b060b9df6bc4f54684de3fe00cd
Author:     Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 13 Jul 2016 10:44:04 +0000
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:03 -0300

perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event()

Following commit will allow BPF script attach to tracepoints.
bpf__foreach_tev() will iterate over all events, not only kprobes.
Rename it to bpf__foreach_event().

Since only group and event are used by caller, there's no need to pass
full 'struct probe_trace_event' to bpf_prog_iter_callback_t. Pass only
these two strings. After this patch bpf_prog_iter_callback_t natually
support tracepoints.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468406646-21642-5-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/bpf-loader.c   |  8 ++++----
 tools/perf/util/bpf-loader.h   | 12 ++++++------
 tools/perf/util/parse-events.c | 16 ++++++++--------
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 8445e89..f227014 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -693,9 +693,9 @@ int bpf__load(struct bpf_object *obj)
 	return 0;
 }
 
-int bpf__foreach_tev(struct bpf_object *obj,
-		     bpf_prog_iter_callback_t func,
-		     void *arg)
+int bpf__foreach_event(struct bpf_object *obj,
+		       bpf_prog_iter_callback_t func,
+		       void *arg)
 {
 	struct bpf_program *prog;
 	int err;
@@ -728,7 +728,7 @@ int bpf__foreach_tev(struct bpf_object *obj,
 				return fd;
 			}
 
-			err = (*func)(tev, fd, arg);
+			err = (*func)(tev->group, tev->event, fd, arg);
 			if (err) {
 				pr_debug("bpf: call back failed, stop iterate\n");
 				return err;
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 941e172..f2b737b 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -46,7 +46,7 @@ struct bpf_object;
 struct parse_events_term;
 #define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
 
-typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev,
+typedef int (*bpf_prog_iter_callback_t)(const char *group, const char *event,
 					int fd, void *arg);
 
 #ifdef HAVE_LIBBPF_SUPPORT
@@ -67,8 +67,8 @@ int bpf__strerror_probe(struct bpf_object *obj, int err,
 int bpf__load(struct bpf_object *obj);
 int bpf__strerror_load(struct bpf_object *obj, int err,
 		       char *buf, size_t size);
-int bpf__foreach_tev(struct bpf_object *obj,
-		     bpf_prog_iter_callback_t func, void *arg);
+int bpf__foreach_event(struct bpf_object *obj,
+		       bpf_prog_iter_callback_t func, void *arg);
 
 int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term,
 		    struct perf_evlist *evlist, int *error_pos);
@@ -107,9 +107,9 @@ static inline int bpf__unprobe(struct bpf_object *obj __maybe_unused) { return 0
 static inline int bpf__load(struct bpf_object *obj __maybe_unused) { return 0; }
 
 static inline int
-bpf__foreach_tev(struct bpf_object *obj __maybe_unused,
-		 bpf_prog_iter_callback_t func __maybe_unused,
-		 void *arg __maybe_unused)
+bpf__foreach_event(struct bpf_object *obj __maybe_unused,
+		   bpf_prog_iter_callback_t func __maybe_unused,
+		   void *arg __maybe_unused)
 {
 	return 0;
 }
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d866824..6b4fff3 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -584,7 +584,7 @@ struct __add_bpf_event_param {
 	struct list_head *head_config;
 };
 
-static int add_bpf_event(struct probe_trace_event *tev, int fd,
+static int add_bpf_event(const char *group, const char *event, int fd,
 			 void *_param)
 {
 	LIST_HEAD(new_evsels);
@@ -595,27 +595,27 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd,
 	int err;
 
 	pr_debug("add bpf event %s:%s and attach bpf program %d\n",
-		 tev->group, tev->event, fd);
+		 group, event, fd);
 
-	err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, tev->group,
-					  tev->event, evlist->error,
+	err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, group,
+					  event, evlist->error,
 					  param->head_config);
 	if (err) {
 		struct perf_evsel *evsel, *tmp;
 
 		pr_debug("Failed to add BPF event %s:%s\n",
-			 tev->group, tev->event);
+			 group, event);
 		list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
 			list_del(&evsel->node);
 			perf_evsel__delete(evsel);
 		}
 		return err;
 	}
-	pr_debug("adding %s:%s\n", tev->group, tev->event);
+	pr_debug("adding %s:%s\n", group, event);
 
 	list_for_each_entry(pos, &new_evsels, node) {
 		pr_debug("adding %s:%s to %p\n",
-			 tev->group, tev->event, pos);
+			 group, event, pos);
 		pos->bpf_fd = fd;
 	}
 	list_splice(&new_evsels, list);
@@ -661,7 +661,7 @@ int parse_events_load_bpf_obj(struct parse_events_evlist *data,
 		goto errout;
 	}
 
-	err = bpf__foreach_tev(obj, add_bpf_event, &param);
+	err = bpf__foreach_event(obj, add_bpf_event, &param);
 	if (err) {
 		snprintf(errbuf, sizeof(errbuf),
 			 "Attach events in BPF object failed");

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

* [tip:perf/core] perf bpf: Support BPF program attach to tracepoints
  2016-07-13 10:44 ` [PATCH 5/5] perf bpf: Support BPF program attach to tracepoints Wang Nan
@ 2016-07-14  7:04   ` tip-bot for Wang Nan
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Wang Nan @ 2016-07-14  7:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, wangnan0, acme, hpa, lizefan, jolsa, ast, linux-kernel,
	tglx

Commit-ID:  b4ee6d415e731b9d8a51451da0ebe33450c355d2
Gitweb:     http://git.kernel.org/tip/b4ee6d415e731b9d8a51451da0ebe33450c355d2
Author:     Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 13 Jul 2016 10:44:05 +0000
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:04 -0300

perf bpf: Support BPF program attach to tracepoints

To support 98b5c2c65c29 ("perf, bpf: allow bpf programs attach to
tracepoints"), this patch allows BPF scripts to select tracepoints in
their section name.

Example:

  # cat test_tracepoint.c
  /*********************************************/
  #include <uapi/linux/bpf.h>
  #define SEC(NAME) __attribute__((section(NAME), used))
  SEC("raw_syscalls:sys_enter")
  int func(void *ctx)
  {
 	/*
 	 * /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/format:
 	 * ...
 	 * field:long id;	offset:8;	size:8;	signed:1;
 	 * ...
 	 * ctx + 8 select 'id'
 	 */
 	u64 id = *((u64 *)(ctx + 8));
 	if (id == 1)
 		return 1;
 	return 0;
  }
  SEC("_write=sys_write")
  int _write(void *ctx)
  {
 	return 1;
  }
  char _license[] SEC("license") = "GPL";
  int _version SEC("version") = LINUX_VERSION_CODE;
  /*********************************************/
  # perf record -e ./test_tracepoint.c  dd if=/dev/zero of=/dev/null count=5
  5+0 records in
  5+0 records out
  2560 bytes (2.6 kB) copied, 6.2281e-05 s, 41.1 MB/s
  [ perf record: Woken up 1 times to write data ]
  # perf script
         dd 13436 [005] 1596.490869: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, 7ffe82470d60, ffffffffffffe020, fffff
         dd 13436 [005] 1596.490871:  perf_bpf_probe:_write: (ffffffff812351e0)
         dd 13436 [005] 1596.490873: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
         dd 13436 [005] 1596.490874:  perf_bpf_probe:_write: (ffffffff812351e0)
         dd 13436 [005] 1596.490876: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
         dd 13436 [005] 1596.490876:  perf_bpf_probe:_write: (ffffffff812351e0)
         dd 13436 [005] 1596.490878: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
         dd 13436 [005] 1596.490879:  perf_bpf_probe:_write: (ffffffff812351e0)
         dd 13436 [005] 1596.490881: raw_syscalls:sys_enter: NR 1 (1, 178d000, 200, ffffffffffffe000, ffffffffffffe020, f
         dd 13436 [005] 1596.490882:  perf_bpf_probe:_write: (ffffffff812351e0)
         dd 13436 [005] 1596.490900: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1f, 40acb8, 7f44bac74700, 7f44baa4fba
         dd 13436 [005] 1596.490901:  perf_bpf_probe:_write: (ffffffff812351e0)
         dd 13436 [005] 1596.490917: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1a, fffffffa, 7f44bac74700, 7f44baa4f
         dd 13436 [005] 1596.490918:  perf_bpf_probe:_write: (ffffffff812351e0)
         dd 13436 [005] 1596.490932: raw_syscalls:sys_enter: NR 1 (2, 7ffe8246e640, 1a, fffffff9, 7f44bac74700, 7f44baa4f
         dd 13436 [005] 1596.490933:  perf_bpf_probe:_write: (ffffffff812351e0)

Committer note:

Further testing:

  # trace --no-sys --event /home/acme/bpf/tracepoint.c cat /etc/passwd > /dev/null
     0.000 raw_syscalls:sys_enter:NR 1 (1, 7f0490504000, c48, 7f0490503010, ffffffffffffffff, 0))
     0.006 perf_bpf_probe:_write:(ffffffff81241bc0))
  #

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1468406646-21642-6-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/bpf-loader.c | 65 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index f227014..1f12e4e 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -37,6 +37,9 @@ DEFINE_PRINT_FN(info, 1)
 DEFINE_PRINT_FN(debug, 1)
 
 struct bpf_prog_priv {
+	bool is_tp;
+	char *sys_name;
+	char *evt_name;
 	struct perf_probe_event pev;
 	bool need_prologue;
 	struct bpf_insn *insns_buf;
@@ -118,6 +121,8 @@ clear_prog_priv(struct bpf_program *prog __maybe_unused,
 	cleanup_perf_probe_events(&priv->pev, 1);
 	zfree(&priv->insns_buf);
 	zfree(&priv->type_mapping);
+	zfree(&priv->sys_name);
+	zfree(&priv->evt_name);
 	free(priv);
 }
 
@@ -269,7 +274,8 @@ nextline:
 }
 
 static int
-parse_prog_config(const char *config_str, struct perf_probe_event *pev)
+parse_prog_config(const char *config_str, const char **p_main_str,
+		  bool *is_tp, struct perf_probe_event *pev)
 {
 	int err;
 	const char *main_str = parse_prog_config_kvpair(config_str, pev);
@@ -277,6 +283,22 @@ parse_prog_config(const char *config_str, struct perf_probe_event *pev)
 	if (IS_ERR(main_str))
 		return PTR_ERR(main_str);
 
+	*p_main_str = main_str;
+	if (!strchr(main_str, '=')) {
+		/* Is a tracepoint event? */
+		const char *s = strchr(main_str, ':');
+
+		if (!s) {
+			pr_debug("bpf: '%s' is not a valid tracepoint\n",
+				 config_str);
+			return -BPF_LOADER_ERRNO__CONFIG;
+		}
+
+		*is_tp = true;
+		return 0;
+	}
+
+	*is_tp = false;
 	err = parse_perf_probe_command(main_str, pev);
 	if (err < 0) {
 		pr_debug("bpf: '%s' is not a valid config string\n",
@@ -292,7 +314,8 @@ config_bpf_program(struct bpf_program *prog)
 {
 	struct perf_probe_event *pev = NULL;
 	struct bpf_prog_priv *priv = NULL;
-	const char *config_str;
+	const char *config_str, *main_str;
+	bool is_tp = false;
 	int err;
 
 	/* Initialize per-program probing setting */
@@ -313,10 +336,19 @@ config_bpf_program(struct bpf_program *prog)
 	pev = &priv->pev;
 
 	pr_debug("bpf: config program '%s'\n", config_str);
-	err = parse_prog_config(config_str, pev);
+	err = parse_prog_config(config_str, &main_str, &is_tp, pev);
 	if (err)
 		goto errout;
 
+	if (is_tp) {
+		char *s = strchr(main_str, ':');
+
+		priv->is_tp = true;
+		priv->sys_name = strndup(main_str, s - main_str);
+		priv->evt_name = strdup(s + 1);
+		goto set_priv;
+	}
+
 	if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
 		pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
 			 config_str, PERF_BPF_PROBE_GROUP);
@@ -339,6 +371,7 @@ config_bpf_program(struct bpf_program *prog)
 	}
 	pr_debug("bpf: config '%s' is ok\n", config_str);
 
+set_priv:
 	err = bpf_program__set_priv(prog, priv, clear_prog_priv);
 	if (err) {
 		pr_debug("Failed to set priv for program '%s'\n", config_str);
@@ -387,7 +420,7 @@ preproc_gen_prologue(struct bpf_program *prog, int n,
 	size_t prologue_cnt = 0;
 	int i, err;
 
-	if (IS_ERR(priv) || !priv)
+	if (IS_ERR(priv) || !priv || priv->is_tp)
 		goto errout;
 
 	pev = &priv->pev;
@@ -544,6 +577,11 @@ static int hook_load_preprocessor(struct bpf_program *prog)
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
 
+	if (priv->is_tp) {
+		priv->need_prologue = false;
+		return 0;
+	}
+
 	pev = &priv->pev;
 	for (i = 0; i < pev->ntevs; i++) {
 		struct probe_trace_event *tev = &pev->tevs[i];
@@ -610,6 +648,13 @@ int bpf__probe(struct bpf_object *obj)
 			err = PTR_ERR(priv);
 			goto out;
 		}
+
+		if (priv->is_tp) {
+			bpf_program__set_tracepoint(prog);
+			continue;
+		}
+
+		bpf_program__set_kprobe(prog);
 		pev = &priv->pev;
 
 		err = convert_perf_probe_events(pev, 1);
@@ -650,7 +695,7 @@ int bpf__unprobe(struct bpf_object *obj)
 		struct bpf_prog_priv *priv = bpf_program__priv(prog);
 		int i;
 
-		if (IS_ERR(priv) || !priv)
+		if (IS_ERR(priv) || !priv || priv->is_tp)
 			continue;
 
 		for (i = 0; i < priv->pev.ntevs; i++) {
@@ -711,6 +756,16 @@ int bpf__foreach_event(struct bpf_object *obj,
 			return -BPF_LOADER_ERRNO__INTERNAL;
 		}
 
+		if (priv->is_tp) {
+			fd = bpf_program__fd(prog);
+			err = (*func)(priv->sys_name, priv->evt_name, fd, arg);
+			if (err) {
+				pr_debug("bpf: tracepoint call back failed, stop iterate\n");
+				return err;
+			}
+			continue;
+		}
+
 		pev = &priv->pev;
 		for (i = 0; i < pev->ntevs; i++) {
 			tev = &pev->tevs[i];

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

end of thread, other threads:[~2016-07-14  7:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-13 10:44 [PATCH 0/5] perf bpf: Allow BPF programs attach to tracepoints Wang Nan
2016-07-13 10:44 ` [PATCH 1/5] tools lib bpf: New API to adjust type of a BPF program Wang Nan
2016-07-14  7:02   ` [tip:perf/core] " tip-bot for Wang Nan
2016-07-13 10:44 ` [PATCH 2/5] tools lib bpf: Report error when kernel doesn't support program type Wang Nan
2016-07-14  7:03   ` [tip:perf/core] " tip-bot for Wang Nan
2016-07-13 10:44 ` [PATCH 3/5] perf tools: event parser: Add const qualifier to evt_name and sys_name Wang Nan
2016-07-14  7:03   ` [tip:perf/core] perf " tip-bot for Wang Nan
2016-07-13 10:44 ` [PATCH 4/5] perf bpf: Rename bpf__foreach_tev() to bpf__foreach_event() Wang Nan
2016-07-14  7:04   ` [tip:perf/core] " tip-bot for Wang Nan
2016-07-13 10:44 ` [PATCH 5/5] perf bpf: Support BPF program attach to tracepoints Wang Nan
2016-07-14  7:04   ` [tip:perf/core] " tip-bot for Wang Nan
2016-07-13 10:44 ` [PATCH 5/5] " Wang Nan
2016-07-13 18:56 ` [PATCH 0/5] perf bpf: Allow BPF programs " Arnaldo Carvalho de Melo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.