mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Wang Nan <wangnan0@huawei.com>
To: <acme@redhat.com>, <mingo@kernel.org>, <ast@plumgrid.com>
Cc: <linux-kernel@vger.kernel.org>, <lizefan@huawei.com>,
	<pi3orama@163.com>, Wang Nan <wangnan0@huawei.com>,
	Brendan Gregg <brendan.d.gregg@gmail.com>,
	Daniel Borkmann <daniel@iogearbox.net>,
	David Ahern <dsahern@gmail.com>, "He Kuang" <hekuang@huawei.com>,
	Jiri Olsa <jolsa@kernel.org>, Kaixu Xia <xiakaixu@huawei.com>,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
	Namhyung Kim <namhyung@kernel.org>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>
Subject: [PATCH 18/31] perf test: Add 'perf test BPF'
Date: Sat, 29 Aug 2015 04:21:52 +0000	[thread overview]
Message-ID: <1440822125-52691-19-git-send-email-wangnan0@huawei.com> (raw)
In-Reply-To: <1440822125-52691-1-git-send-email-wangnan0@huawei.com>

This patch adds BPF testcase for testing BPF event filtering.

By utilizing the result of 'perf test LLVM', this patch compiles the
eBPF sample program then test it ability. The BPF script in 'perf test
LLVM' collects half of execution of epoll_pwait(). This patch runs 111
times of it, so the resule should contains 56 samples.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David Ahern <dsahern@gmail.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/n/1440151770-129878-16-git-send-email-wangnan0@huawei.com
---
 tools/perf/tests/Build          |   1 +
 tools/perf/tests/bpf.c          | 170 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/builtin-test.c |   4 +
 tools/perf/tests/llvm.c         |  19 +++++
 tools/perf/tests/llvm.h         |   1 +
 tools/perf/tests/tests.h        |   1 +
 tools/perf/util/bpf-loader.c    |  14 ++++
 tools/perf/util/bpf-loader.h    |   8 ++
 8 files changed, 218 insertions(+)
 create mode 100644 tools/perf/tests/bpf.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 8c98409..7ceb448 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -33,6 +33,7 @@ perf-y += parse-no-sample-id-all.o
 perf-y += kmod-path.o
 perf-y += thread-map.o
 perf-y += llvm.o llvm-src.o
+perf-y += bpf.o
 
 $(OUTPUT)tests/llvm-src.c: tests/bpf-script-example.c
 	$(Q)echo '#include <tests/llvm.h>' > $@
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
new file mode 100644
index 0000000..6c238ca
--- /dev/null
+++ b/tools/perf/tests/bpf.c
@@ -0,0 +1,170 @@
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <util/bpf-loader.h>
+#include <util/evlist.h>
+#include "tests.h"
+#include "llvm.h"
+#include "debug.h"
+#define NR_ITERS       111
+
+#ifdef HAVE_LIBBPF_SUPPORT
+
+static int epoll_pwait_loop(void)
+{
+	int i;
+
+	/* Should fail NR_ITERS times */
+	for (i = 0; i < NR_ITERS; i++)
+		epoll_pwait(-(i + 1), NULL, 0, 0, NULL);
+	return 0;
+}
+
+static int prepare_bpf(void *obj_buf, size_t obj_buf_sz)
+{
+	int err;
+	char errbuf[BUFSIZ];
+
+	err = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, NULL);
+	if (err) {
+		bpf__strerror_prepare_load("[buffer]", false, err, errbuf,
+					   sizeof(errbuf));
+		fprintf(stderr, " (%s)", errbuf);
+		return TEST_FAIL;
+	}
+
+	err = bpf__probe();
+	if (err) {
+		bpf__strerror_load(err, errbuf, sizeof(errbuf));
+		fprintf(stderr, " (%s)", errbuf);
+		if (getuid() != 0)
+			fprintf(stderr, " (try run as root)");
+		return TEST_FAIL;
+	}
+
+	err = bpf__load();
+	if (err) {
+		bpf__strerror_load(err, errbuf, sizeof(errbuf));
+		fprintf(stderr, " (%s)", errbuf);
+		return TEST_FAIL;
+	}
+
+	return 0;
+}
+
+static int do_test(void)
+{
+	struct record_opts opts = {
+		.target = {
+			.uid = UINT_MAX,
+			.uses_mmap = true,
+		},
+		.freq	      = 0,
+		.mmap_pages   = 256,
+		.default_interval = 1,
+	};
+
+	int err, i, count = 0;
+	char pid[16];
+	char sbuf[STRERR_BUFSIZE];
+	struct perf_evlist *evlist;
+
+	snprintf(pid, sizeof(pid), "%d", getpid());
+	pid[sizeof(pid) - 1] = '\0';
+	opts.target.tid = opts.target.pid = pid;
+
+	/* Instead of perf_evlist__new_default, don't add default events */
+	evlist = perf_evlist__new();
+	if (!evlist) {
+		pr_debug("No ehough memory to create evlist\n");
+		return -ENOMEM;
+	}
+
+	err = perf_evlist__create_maps(evlist, &opts.target);
+	if (err < 0) {
+		pr_debug("Not enough memory to create thread/cpu maps\n");
+		goto out_delete_evlist;
+	}
+
+	err = perf_evlist__add_bpf(evlist);
+	if (err) {
+		fprintf(stderr, " (Failed to add events selected by BPF)");
+		goto out_delete_evlist;
+	}
+
+	perf_evlist__config(evlist, &opts);
+
+	err = perf_evlist__open(evlist);
+	if (err < 0) {
+		pr_debug("perf_evlist__open: %s\n",
+			 strerror_r(errno, sbuf, sizeof(sbuf)));
+		goto out_delete_evlist;
+	}
+
+	err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
+	if (err < 0) {
+		pr_debug("perf_evlist__mmap: %s\n",
+			 strerror_r(errno, sbuf, sizeof(sbuf)));
+		goto out_delete_evlist;
+	}
+
+	perf_evlist__enable(evlist);
+	epoll_pwait_loop();
+	perf_evlist__disable(evlist);
+
+	for (i = 0; i < evlist->nr_mmaps; i++) {
+		union perf_event *event;
+
+		while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
+			const u32 type = event->header.type;
+
+			if (type == PERF_RECORD_SAMPLE)
+				count ++;
+		}
+	}
+
+	if (count != (NR_ITERS + 1) / 2) {
+		fprintf(stderr, " (filter result incorrect)");
+		err = -EBADF;
+	}
+
+out_delete_evlist:
+	perf_evlist__delete(evlist);
+	if (err)
+		return TEST_FAIL;
+	return 0;
+}
+
+int test__bpf(void)
+{
+	int err;
+	void *obj_buf;
+	size_t obj_buf_sz;
+
+	test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz);
+	if (!obj_buf || !obj_buf_sz) {
+		if (verbose == 0)
+			fprintf(stderr, " (fix 'perf test LLVM' first)");
+		return TEST_SKIP;
+	}
+
+	err = prepare_bpf(obj_buf, obj_buf_sz);
+	if (err)
+		goto out;
+
+	err = do_test();
+	if (err)
+		goto out;
+out:
+	bpf__unprobe();
+	bpf__clear();
+	if (err)
+		return TEST_FAIL;
+	return 0;
+}
+
+#else
+int test__bpf(void)
+{
+	return TEST_SKIP;
+}
+#endif
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 1a349e8..c32c836 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -183,6 +183,10 @@ static struct test {
 		.cleanup = test__llvm_cleanup,
 	},
 	{
+		.desc = "Test BPF filter",
+		.func = test__bpf,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index 236bf39..fd5fdb0 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -174,3 +174,22 @@ void test__llvm_cleanup(void)
 			(~((unsigned long)page_size - 1));
 	munmap((void *)boundary, buf_end - boundary);
 }
+
+void
+test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz)
+{
+	*p_obj_buf = NULL;
+	*p_obj_buf_sz = 0;
+
+	if (!p_test_llvm__bpf_result) {
+		test__llvm_prepare();
+		test__llvm();
+		test__llvm_cleanup();
+	}
+
+	if (!p_test_llvm__bpf_result)
+		return;
+
+	*p_obj_buf = p_test_llvm__bpf_result->object;
+	*p_obj_buf_sz = p_test_llvm__bpf_result->size;
+}
diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
index 1e89e46..2fd7ed6 100644
--- a/tools/perf/tests/llvm.h
+++ b/tools/perf/tests/llvm.h
@@ -10,5 +10,6 @@ struct test_llvm__bpf_result {
 
 extern struct test_llvm__bpf_result *p_test_llvm__bpf_result;
 extern const char test_llvm__bpf_prog[];
+void test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz);
 
 #endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 0d79f04..f8ded73 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -65,6 +65,7 @@ int test__thread_map(void);
 int test__llvm(void);
 void test__llvm_prepare(void);
 void test__llvm_cleanup(void);
+int test__bpf(void);
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index c2aafe2..95e529b 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -153,6 +153,20 @@ sync_bpf_program_pev(struct bpf_program *prog)
 	return 0;
 }
 
+int bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz,
+			     const char *name)
+{
+	struct bpf_object *obj;
+
+	obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, name);
+	if (!obj) {
+		pr_debug("bpf: failed to load buffer\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 int bpf__prepare_load(const char *filename, bool source)
 {
 	struct bpf_object *obj;
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 97aed65..dead4d4 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -19,6 +19,8 @@ typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev,
 
 #ifdef HAVE_LIBBPF_SUPPORT
 int bpf__prepare_load(const char *filename, bool source);
+int bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz,
+			     const char *name);
 int bpf__strerror_prepare_load(const char *filename, bool source,
 			       int err, char *buf, size_t size);
 int bpf__probe(void);
@@ -39,6 +41,12 @@ static inline int bpf__prepare_load(const char *filename __maybe_unused,
 	return -1;
 }
 
+static inline int bpf__prepare_load_buffer(void *obj_buf __maybe_unused,
+					   size_t obj_buf_sz __maybe_unused)
+{
+	return bpf__prepare_load(NULL, false);
+}
+
 static inline int bpf__probe(void) { return 0; }
 static inline int bpf__unprobe(void) { return 0; }
 static inline int bpf__load(void) { return 0; }
-- 
2.1.0


  parent reply	other threads:[~2015-08-29  4:29 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-29  4:21 [GIT PULL 00/31] perf tools: filtering events using eBPF programs Wang Nan
2015-08-29  4:21 ` [PATCH 01/31] bpf tools: New API to get name from a BPF object Wang Nan
2015-08-29  4:21 ` [PATCH 02/31] perf tools: Don't set cmdline_group_boundary if no evsel is collected Wang Nan
2015-08-31 19:20   ` Arnaldo Carvalho de Melo
2015-09-01 10:37     ` Wangnan (F)
2015-09-01 10:38     ` Jiri Olsa
2015-09-01 12:44       ` Wangnan (F)
2015-09-02  2:53   ` [PATCH] perf tools: Don't set leader if parser doesn't collect an evsel Wang Nan
2015-09-02  3:01     ` Wangnan (F)
2015-09-02  5:57     ` 平松雅巳 / HIRAMATU,MASAMI
2015-09-02  6:09       ` Wangnan (F)
     [not found]       ` <1441176553-116129-1-git-send-email-wangnan0@huawei.com>
2015-09-02  6:53         ` [PATCH] perf tools: Don't write to evsel if parser doesn't collect evsel Wangnan (F)
2015-09-02 10:31           ` 平松雅巳 / HIRAMATU,MASAMI
2015-09-02 11:54           ` Jiri Olsa
2015-09-02 12:05             ` pi3orama
2015-09-02 12:46               ` Jiri Olsa
2015-09-02 13:55               ` Arnaldo Carvalho de Melo
2015-09-02 14:04                 ` pi3orama
2015-09-02 14:43                   ` Arnaldo Carvalho de Melo
2015-09-02 22:24                     ` pi3orama
2015-08-29  4:21 ` [PATCH 03/31] perf tools: Introduce dummy evsel Wang Nan
2015-08-31 19:38   ` Arnaldo Carvalho de Melo
2015-09-03  0:11   ` Namhyung Kim
2015-09-03  0:42     ` pi3orama
2015-09-06  5:55   ` [PATCH] perf tools: Allow BPF placeholder dummy events to collect --filter options Wang Nan
2015-09-06  5:56     ` [PATCH] perf tools: Sync setting of real bpf events with placeholder Wang Nan
2015-08-29  4:21 ` [PATCH 04/31] perf tools: Make perf depend on libbpf Wang Nan
2015-08-29  4:21 ` [PATCH 05/31] perf ebpf: Add the libbpf glue Wang Nan
2015-08-29  4:21 ` [PATCH 06/31] perf tools: Enable passing bpf object file to --event Wang Nan
2015-08-29  4:21 ` [PATCH 07/31] perf probe: Attach trace_probe_event with perf_probe_event Wang Nan
2015-09-02  4:32   ` Namhyung Kim
2015-09-02  5:40     ` Wangnan (F)
2015-08-29  4:21 ` [PATCH 08/31] perf record, bpf: Parse and probe eBPF programs probe points Wang Nan
2015-08-29  4:21 ` [PATCH 09/31] perf bpf: Collect 'struct perf_probe_event' for bpf_program Wang Nan
2015-08-29  4:21 ` [PATCH 10/31] perf record: Load all eBPF object into kernel Wang Nan
2015-08-29  4:21 ` [PATCH 11/31] perf tools: Add bpf_fd field to evsel and config it Wang Nan
2015-08-29  4:21 ` [PATCH 12/31] perf tools: Allow filter option to be applied to bof object Wang Nan
2015-08-29  4:21 ` [PATCH 13/31] perf tools: Attach eBPF program to perf event Wang Nan
2015-08-29  4:21 ` [PATCH 14/31] perf tools: Suppress probing messages when probing by BPF loading Wang Nan
2015-09-03  0:20   ` Namhyung Kim
2015-09-03  2:42     ` 平松雅巳 / HIRAMATU,MASAMI
2015-09-03 12:10     ` [PATCH perf/core ] perf-probe: Output the result of adding/deleting probe in buildin-probe Masami Hiramatsu
2015-09-03 12:18       ` 平松雅巳 / HIRAMATU,MASAMI
2015-09-03 17:25         ` Namhyung Kim
2015-09-03 20:28       ` Arnaldo Carvalho de Melo
2015-09-04  1:30         ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-29  4:21 ` [PATCH 15/31] perf record: Add clang options for compiling BPF scripts Wang Nan
2015-08-29  4:21 ` [PATCH 16/31] perf tools: Infrastructure for compiling scriptlets when passing '.c' to --event Wang Nan
2015-08-29  4:21 ` [PATCH 17/31] perf tests: Enforce LLVM test for BPF test Wang Nan
2015-09-01  5:59   ` Wangnan (F)
2015-08-29  4:21 ` Wang Nan [this message]
2015-09-02 12:45   ` [PATCH 18/31] perf test: Add 'perf test BPF' Namhyung Kim
2015-09-05 12:21     ` Wang Nan
2015-08-29  4:21 ` [PATCH 19/31] bpf tools: Load a program with different instances using preprocessor Wang Nan
2015-08-29  4:21 ` [PATCH 20/31] perf probe: Reset args and nargs for probe_trace_event when failure Wang Nan
2015-08-29  4:21 ` [PATCH 21/31] perf tools: Move linux/filter.h to tools/include Wang Nan
2015-08-31 20:35   ` Arnaldo Carvalho de Melo
2015-09-01 19:39   ` Arnaldo Carvalho de Melo
2015-09-01 19:47     ` Arnaldo Carvalho de Melo
2015-09-01 21:08     ` pi3orama
2015-09-01 21:43       ` Arnaldo Carvalho de Melo
2015-09-08 14:31   ` [tip:perf/core] perf tools: Copy " tip-bot for He Kuang
2015-08-29  4:21 ` [PATCH 22/31] perf tools: Add BPF_PROLOGUE config options for further patches Wang Nan
2015-08-31 20:39   ` Arnaldo Carvalho de Melo
2015-09-01  6:59   ` Wang Nan
2015-09-01  6:59     ` [PATCH 23/31] perf tools: Introduce regs_query_register_offset() for x86 Wang Nan
2015-09-01 11:47       ` 平松雅巳 / HIRAMATU,MASAMI
2015-09-01 13:52         ` Wangnan (F)
2015-09-01 14:50           ` Arnaldo Carvalho de Melo
2015-09-01 14:14         ` Arnaldo Carvalho de Melo
2015-09-01 15:54           ` 平松雅巳 / HIRAMATU,MASAMI
2015-09-06  6:02             ` Wangnan (F)
2015-09-06  6:04               ` [PATCH] perf test: Enforce LLVM test, add kbuild test Wang Nan
2015-09-06  6:04                 ` [PATCH] perf test: Test BPF prologue Wang Nan
2015-09-02 14:08     ` [PATCH 22/31] perf tools: Add BPF_PROLOGUE config options for further patches Namhyung Kim
2015-08-29  4:21 ` [PATCH 23/31] perf tools: Introduce arch_get_reg_info() for x86 Wang Nan
2015-08-31 20:43   ` Arnaldo Carvalho de Melo
2015-09-01  2:39     ` Wangnan (F)
2015-08-29  4:21 ` [PATCH 24/31] perf tools: Add prologue for BPF programs for fetching arguments Wang Nan
2015-08-29  4:21 ` [PATCH 25/31] perf tools: Generate prologue for BPF programs Wang Nan
2015-08-29  4:22 ` [PATCH 26/31] perf tools: Use same BPF program if arguments are identical Wang Nan
2015-08-29  4:22 ` [PATCH 27/31] perf record: Support custom vmlinux path Wang Nan
2015-09-01 20:19   ` Arnaldo Carvalho de Melo
2015-09-01 20:21     ` Arnaldo Carvalho de Melo
2015-09-01 21:00       ` pi3orama
2015-09-01 21:33         ` Arnaldo Carvalho de Melo
2015-08-29  4:22 ` [PATCH 28/31] perf probe: Init symbol as kprobe Wang Nan
2015-09-01 20:11   ` Arnaldo Carvalho de Melo
2015-09-02  1:22     ` Wangnan (F)
2015-09-02  1:38     ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-29  4:22 ` [PATCH 29/31] perf tools: Support attach BPF program on uprobe events Wang Nan
2015-08-29  4:22 ` [PATCH 30/31] perf tools: Fix cross compiling error Wang Nan
2015-08-29  4:22 ` [PATCH 31/31] tools lib traceevent: Support function __get_dynamic_array_len Wang Nan
2015-09-08 14:31   ` [tip:perf/core] " tip-bot for He Kuang

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=1440822125-52691-19-git-send-email-wangnan0@huawei.com \
    --to=wangnan0@huawei.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@redhat.com \
    --cc=ast@plumgrid.com \
    --cc=brendan.d.gregg@gmail.com \
    --cc=daniel@iogearbox.net \
    --cc=dsahern@gmail.com \
    --cc=hekuang@huawei.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=pi3orama@163.com \
    --cc=xiakaixu@huawei.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

all inboxes | Powered by JetHome®