linux-kernel.vger.kernel.org archive mirror
 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 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).