linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Wang Nan <wangnan0@huawei.com>
To: <acme@kernel.org>
Cc: <lizefan@huawei.com>, <linux-kernel@vger.kernel.org>,
	<pi3orama@163.com>, Wang Nan <wangnan0@huawei.com>,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	Alexei Starovoitov <ast@kernel.org>, Jiri Olsa <jolsa@kernel.org>
Subject: [PATCH 5/5] perf bpf: Support BPF program attach to tracepoints
Date: Wed, 13 Jul 2016 10:44:05 +0000	[thread overview]
Message-ID: <1468406646-21642-6-git-send-email-wangnan0@huawei.com> (raw)
In-Reply-To: <1468406646-21642-1-git-send-email-wangnan0@huawei.com>

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

  parent reply	other threads:[~2016-07-13 10:45 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Wang Nan [this message]
2016-07-14  7:04   ` [tip:perf/core] perf bpf: Support BPF program attach to tracepoints 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1468406646-21642-6-git-send-email-wangnan0@huawei.com \
    --to=wangnan0@huawei.com \
    --cc=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=ast@kernel.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=pi3orama@163.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is 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).