Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1270086

[PATCH 13/13] perf tools: Use same BPF program if arguments are identical

From Wang Nan <wangnan0@huawei.com>
Newsgroups linux.kernel
Subject [PATCH 13/13] perf tools: Use same BPF program if arguments are identical
Date 2015-11-16 14:00 +0100
Message-ID <qvry2-7qr-9@gated-at.bofh.it> (permalink)
References <qvrom-7n2-5@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


This patch allows creating only one BPF program for different
'probe_trace_event'(tev) generated by one 'perf_probe_event'(pev), if
their prologues are identical.

This is done by comparing argument list of different tev, and maps type
of prologue and tev using a mapping array. This patch utilizes qsort to
sort tevs. After sorting, tevs with identical argument list will be
grouped together.

Test result:

Sample BPF program:

 SEC("inlines=no\n"
     "func=SyS_dup? oldfd")
 int func(void *ctx)
 {
     return 1;
 }

It would probe at SyS_dup2 and SyS_dup3, extracts oldfd as its argument.

Following cmdline shows BPF program loaded into kernel by perf:

 # ./perf record  -e  ./test_bpf_arg.c sleep 4 & sleep 1 && ls /proc/$!/fd/ -l | grep bpf-prog

Before this patch:

 # ./perf record  -e  ./test_bpf_arg.c sleep 4 & sleep 1 && ls /proc/$!/fd/ -l | grep bpf-prog
 [1] 24858
 lrwx------ 1 root root 64 Nov 14 04:09 3 -> anon_inode:bpf-prog
 lrwx------ 1 root root 64 Nov 14 04:09 4 -> anon_inode:bpf-prog
 ...

After this patch:

 # ./perf record  -e  ./test_bpf_arg.c sleep 4 & sleep 1 && ls /proc/$!/fd/ -l | grep bpf-prog
 [1] 25699
 lrwx------ 1 root root 64 Nov 14 04:10 3 -> anon_inode:bpf-prog
 ...

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
---
 tools/perf/util/bpf-loader.c | 136 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 129 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index cad0d0f..86c50b9 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -38,6 +38,8 @@ struct bpf_prog_priv {
 	struct perf_probe_event pev;
 	bool need_prologue;
 	struct bpf_insn *insns_buf;
+	int nr_types;
+	int *type_mapping;
 };
 
 static bool libbpf_initialized;
@@ -113,6 +115,7 @@ bpf_prog_priv__clear(struct bpf_program *prog __maybe_unused,
 
 	cleanup_perf_probe_events(&priv->pev, 1);
 	zfree(&priv->insns_buf);
+	zfree(&priv->type_mapping);
 	free(priv);
 }
 
@@ -381,7 +384,7 @@ preproc_gen_prologue(struct bpf_program *prog, int n,
 	struct bpf_prog_priv *priv;
 	struct bpf_insn *buf;
 	size_t prologue_cnt = 0;
-	int err;
+	int i, err;
 
 	err = bpf_program__get_private(prog, (void **)&priv);
 	if (err || !priv)
@@ -389,10 +392,20 @@ preproc_gen_prologue(struct bpf_program *prog, int n,
 
 	pev = &priv->pev;
 
-	if (n < 0 || n >= pev->ntevs)
+	if (n < 0 || n >= priv->nr_types)
 		goto errout;
 
-	tev = &pev->tevs[n];
+	/* Find a tev belongs to that type */
+	for (i = 0; i < pev->ntevs; i++)
+		if (priv->type_mapping[i] == n)
+			break;
+
+	if (i >= pev->ntevs) {
+		pr_debug("Internal error: prologue type %d not found\n", n);
+		return -BPF_LOADER_ERRNO__PROLOGUE;
+	}
+
+	tev = &pev->tevs[i];
 
 	buf = priv->insns_buf;
 	err = bpf__gen_prologue(tev->args, tev->nargs,
@@ -423,6 +436,101 @@ errout:
 	return -BPF_LOADER_ERRNO__PROLOGUE;
 }
 
+/*
+ * compare_tev_args is reflexive, transitive and antisymmetric.
+ * I can proof it but this margin is too narrow to contain.
+ */
+static int compare_tev_args(const void *ptev1, const void *ptev2)
+{
+	int i, ret;
+	const struct probe_trace_event *tev1 =
+		*(const struct probe_trace_event **)ptev1;
+	const struct probe_trace_event *tev2 =
+		*(const struct probe_trace_event **)ptev2;
+
+	ret = tev2->nargs - tev1->nargs;
+	if (ret)
+		return ret;
+
+	for (i = 0; i < tev1->nargs; i++) {
+		struct probe_trace_arg *arg1, *arg2;
+		struct probe_trace_arg_ref *ref1, *ref2;
+
+		arg1 = &tev1->args[i];
+		arg2 = &tev2->args[i];
+
+		ret = strcmp(arg1->value, arg2->value);
+		if (ret)
+			return ret;
+
+		ref1 = arg1->ref;
+		ref2 = arg2->ref;
+
+		while (ref1 && ref2) {
+			ret = ref2->offset - ref1->offset;
+			if (ret)
+				return ret;
+
+			ref1 = ref1->next;
+			ref2 = ref2->next;
+		}
+
+		if (ref1 || ref2)
+			return ref2 ? 1 : -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Assign a type number to each tevs in a pev.
+ * mapping is an array with same slots as tevs in that pev.
+ * nr_types will be set to number of types.
+ */
+static int map_prologue(struct perf_probe_event *pev, int *mapping,
+			int *nr_types)
+{
+	int i, type = 0;
+	struct probe_trace_event **ptevs;
+
+	size_t array_sz = sizeof(*ptevs) * pev->ntevs;
+
+	ptevs = malloc(array_sz);
+	if (!ptevs) {
+		pr_debug("No ehough memory: alloc ptevs failed\n");
+		return -ENOMEM;
+	}
+
+	pr_debug("In map_prologue, ntevs=%d\n", pev->ntevs);
+	for (i = 0; i < pev->ntevs; i++)
+		ptevs[i] = &pev->tevs[i];
+
+	qsort(ptevs, pev->ntevs, sizeof(*ptevs),
+	      compare_tev_args);
+
+	for (i = 0; i < pev->ntevs; i++) {
+		int n;
+
+		n = ptevs[i] - pev->tevs;
+		if (i == 0) {
+			mapping[n] = type;
+			pr_debug("mapping[%d]=%d\n", n, type);
+			continue;
+		}
+
+		if (compare_tev_args(ptevs + i, ptevs + i - 1) == 0)
+			mapping[n] = type;
+		else
+			mapping[n] = ++type;
+
+		pr_debug("mapping[%d]=%d\n", n, mapping[n]);
+	}
+	free(ptevs);
+	*nr_types = type + 1;
+
+	return 0;
+}
+
 static int hook_load_preprocessor(struct bpf_program *prog)
 {
 	struct perf_probe_event *pev;
@@ -462,7 +570,19 @@ static int hook_load_preprocessor(struct bpf_program *prog)
 		return -ENOMEM;
 	}
 
-	err = bpf_program__set_prep(prog, pev->ntevs,
+	priv->type_mapping = malloc(sizeof(int) * pev->ntevs);
+	if (!priv->type_mapping) {
+		pr_debug("No enough memory: alloc type_mapping failed\n");
+		return -ENOMEM;
+	}
+	memset(priv->type_mapping, 0xff,
+	       sizeof(int) * pev->ntevs);
+
+	err = map_prologue(pev, priv->type_mapping, &priv->nr_types);
+	if (err)
+		return err;
+
+	err = bpf_program__set_prep(prog, priv->nr_types,
 				    preproc_gen_prologue);
 	return err;
 }
@@ -596,9 +716,11 @@ int bpf__foreach_tev(struct bpf_object *obj,
 		for (i = 0; i < pev->ntevs; i++) {
 			tev = &pev->tevs[i];
 
-			if (priv->need_prologue)
-				fd = bpf_program__nth_fd(prog, i);
-			else
+			if (priv->need_prologue) {
+				int type = priv->type_mapping[i];
+
+				fd = bpf_program__nth_fd(prog, type);
+			} else
 				fd = bpf_program__fd(prog);
 
 			if (fd < 0) {
-- 
1.8.3.4

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

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 00/13] perf tools: bpf: Improve BPF program ability Wang Nan <wangnan0@huawei.com> - 2015-11-16 13:50 +0100
  [PATCH 03/13] perf tools: Allow BPF program attach to uprobe events Wang Nan <wangnan0@huawei.com> - 2015-11-16 13:50 +0100
    Re: [PATCH 03/13] perf tools: Allow BPF program attach to uprobe  events Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-16 15:20 +0100
    [tip:perf/core] perf bpf:   Allow BPF program attach to uprobe events tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
  [PATCH 10/13] perf tools: Add prologue for BPF programs for fetching arguments Wang Nan <wangnan0@huawei.com> - 2015-11-16 13:50 +0100
    [tip:perf/core] perf bpf:   Add prologue for BPF programs for fetching arguments tip-bot for He Kuang <tipbot@zytor.com> - 2015-11-23 17:10 +0100
  [PATCH 04/13] perf tools: Allow BPF program attach to modules Wang Nan <wangnan0@huawei.com> - 2015-11-16 13:50 +0100
    [tip:perf/core] perf bpf:   Allow attaching BPF programs to modules symbols tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
  [PATCH 07/13] bpf tools: Load a program with different instances using preprocessor Wang Nan <wangnan0@huawei.com> - 2015-11-16 13:50 +0100
    Re: [PATCH 07/13] bpf tools: Load a program with different instances  using preprocessor Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-16 20:10 +0100
      Re: [PATCH 07/13] bpf tools: Load a program with different instances  using preprocessor "Wangnan (F)" <wangnan0@huawei.com> - 2015-11-17 05:00 +0100
    [tip:perf/core] bpf tools:   Load a program with different instances using preprocessor tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
  [PATCH 13/13] perf tools: Use same BPF program if arguments are identical Wang Nan <wangnan0@huawei.com> - 2015-11-16 14:00 +0100
    Re: [PATCH 13/13] perf tools: Use same BPF program if arguments are  identical "Wangnan (F)" <wangnan0@huawei.com> - 2015-11-17 04:10 +0100
      Re: [PATCH 13/13] perf tools: Use same BPF program if arguments are  identical Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 14:20 +0100
  [PATCH 12/13] perf test: Test BPF prologue Wang Nan <wangnan0@huawei.com> - 2015-11-16 14:00 +0100
    Re: [PATCH 12/13] perf test: Test BPF prologue Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 02:30 +0100
      Re: [PATCH 12/13] perf test: Test BPF prologue "Wangnan (F)" <wangnan0@huawei.com> - 2015-11-17 02:40 +0100
      Re: [PATCH 12/13] perf test: Test BPF prologue "Wangnan (F)" <wangnan0@huawei.com> - 2015-11-17 05:40 +0100
        Re: [PATCH 12/13] perf test: Test BPF prologue Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 13:30 +0100
      [PATCH 0/5] perf tools: Improve BPF support Wang Nan <wangnan0@huawei.com> - 2015-11-17 09:40 +0100
        [PATCH 5/5] perf test: Mute test cases if verbose == 0 Wang Nan <wangnan0@huawei.com> - 2015-11-17 09:40 +0100
          Re: [PATCH 5/5] perf test: Mute test cases if verbose == 0 Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 14:20 +0100
          [tip:perf/core] perf test:   Mute test cases error messages if verbose == 0 tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:20 +0100
        [PATCH 2/5] perf tools: Use same BPF program if arguments are identical Wang Nan <wangnan0@huawei.com> - 2015-11-17 09:40 +0100
          [tip:perf/core] perf bpf:   Use same BPF program if arguments are identical tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
        [PATCH 4/5] perf test: Print result for each subtest for BPF Wang Nan <wangnan0@huawei.com> - 2015-11-17 09:40 +0100
          [tip:perf/core] perf test: Print result for each BPF subtest tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:20 +0100
        [PATCH 1/5] perf test: Fix 2 bugs in 'perf test BPF' Wang Nan <wangnan0@huawei.com> - 2015-11-17 09:40 +0100
          Re: [PATCH 1/5] perf test: Fix 2 bugs in 'perf test BPF' Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 14:00 +0100
            Re: [PATCH 1/5] perf test: Fix 2 bugs in 'perf test BPF' pi3orama <pi3orama@163.com> - 2015-11-17 14:10 +0100
              Re: [PATCH 1/5] perf test: Fix 2 bugs in 'perf test BPF' Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 14:40 +0100
          [tip:perf/core] perf test: Fix 'perf test BPF'   when it fails to find a suitable vmlinux tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
        [PATCH 3/5] perf test: Print result for each subtest for llvm Wang Nan <wangnan0@huawei.com> - 2015-11-17 09:40 +0100
          Re: [PATCH 3/5] perf test: Print result for each subtest for llvm Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 14:10 +0100
          [tip:perf/core] perf test: Print result for each LLVM subtest tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:20 +0100
      Re: [PATCH 12/13] perf test: Test BPF prologue "Wangnan (F)" <wangnan0@huawei.com> - 2015-11-17 09:50 +0100
      [PATCH] perf record: Support custom vmlinux path Wang Nan <wangnan0@huawei.com> - 2015-11-17 11:00 +0100
        Re: [PATCH] perf record: Support custom vmlinux path Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 13:40 +0100
          Re: [PATCH] perf record: Support custom vmlinux path Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-17 13:50 +0100
            Re: [PATCH] perf record: Support custom vmlinux path pi3orama <pi3orama@163.com> - 2015-11-17 13:50 +0100
            [PATCH 0/2] perf tools: Builtin options related improvements Wang Nan <wangnan0@huawei.com> - 2015-11-19 15:10 +0100
              [PATCH 2/2] perf record: Support custom vmlinux path Wang Nan <wangnan0@huawei.com> - 2015-11-19 15:10 +0100
              [PATCH 1/2] perf tools: Always give options even it not compiled Wang Nan <wangnan0@huawei.com> - 2015-11-19 15:10 +0100
                RE: [PATCH 1/2] perf tools: Always give options even it not compiled 平松雅巳 / HIRAMATU,MASAMI   <masami.hiramatsu.pt@hitachi.com> - 2015-11-20 12:00 +0100
                Re: [PATCH 1/2] perf tools: Always give options even it not compiled "Wangnan (F)" <wangnan0@huawei.com> - 2015-11-26 09:10 +0100
                Re: [PATCH 1/2] perf tools: Always give options even it not compiled "Wangnan (F)" <wangnan0@huawei.com> - 2015-11-26 10:10 +0100
    [tip:perf/core] perf test:   Test the BPF prologue adding infrastructure tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
  [PATCH 06/13] perf tools: Allow BPF program config probing options Wang Nan <wangnan0@huawei.com> - 2015-11-16 14:00 +0100
    [tip:perf/core] perf bpf:   Allow BPF program config probing options tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
  [PATCH 08/13] perf tools: Add BPF_PROLOGUE config options for further patches Wang Nan <wangnan0@huawei.com> - 2015-11-16 14:00 +0100
    [tip:perf/core] perf bpf:   Add BPF_PROLOGUE config options for further patches tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
  [PATCH 11/13] perf tools: Generate prologue for BPF programs Wang Nan <wangnan0@huawei.com> - 2015-11-16 14:00 +0100
    [tip:perf/core] perf bpf: Generate prologue for BPF programs tip-bot for Wang Nan <tipbot@zytor.com> - 2015-11-23 17:10 +0100
  [PATCH 02/13] perf probe: Clear probe_trace_event when add_probe_trace_event() fails Wang Nan <wangnan0@huawei.com> - 2015-11-16 14:00 +0100
  Re: [PATCH 00/13] perf tools: bpf: Improve BPF program ability Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-16 15:20 +0100

csiph-web