linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Wang Nan <wangnan0@huawei.com>
Cc: ast@plumgrid.com, brendan.d.gregg@gmail.com,
	a.p.zijlstra@chello.nl, daniel@iogearbox.net, dsahern@gmail.com,
	hekuang@huawei.com, jolsa@kernel.org, lizefan@huawei.com,
	masami.hiramatsu.pt@hitachi.com, namhyung@kernel.org,
	paulus@samba.org, linux-kernel@vger.kernel.org, pi3orama@163.com,
	xiakaixu@huawei.com
Subject: Re: [PATCH 10/31] perf test: Enforce LLVM test for BPF test
Date: Thu, 29 Oct 2015 19:37:44 -0300	[thread overview]
Message-ID: <20151029223744.GK2923@kernel.org> (raw)
In-Reply-To: <1444826502-49291-11-git-send-email-wangnan0@huawei.com>

Em Wed, Oct 14, 2015 at 12:41:21PM +0000, Wang Nan escreveu:
> This patch replaces the original toy BPF program with previous introduced
> bpf-script-example.c. Dynamically embedded it into 'llvm-src.c'.
> 
> The newly introduced BPF program attaches a BPF program at
> 'sys_epoll_pwait()', and collect half samples from it. perf itself never

"collect half samples from it"? Can you rephrase this?

> use that syscall, so further test can verify their result with it.
> 
> Since BPF program require LINUX_VERSION_CODE of runtime kernel, this
> patch computes that code from uname.
> 
> Since the resuling BPF object is useful for further testcases, this patch
> introduces 'prepare' and 'cleanup' method to tests, and makes test__llvm()
> create a MAP_SHARED memory array to hold the resulting object.

I think you're doing lots of things in just one patch, please split it,
for instance, that ->prepare()/->cleanup() should stand on its own, with
a proper changelog, etc.

The LINUX_VERSION_CODE part should probably also be on its own patch,
working much like __FILE__ or __func__, i.e. gcc predefines those, the
bpf code that calls clang to build the provided .c file should do the
same for LINUX_VERSION_CODE, so that bpf scriptlets can rely on it being
defined.

I.e. that compose_source() function, but not just for the 'perf test'
entry, for any bpf scriptlet.
 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> 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: 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/ebpf-6yw9eg0ej3l4jnqhinngkw86@git.kernel.org
> ---
>  tools/perf/tests/Build          |   9 +++-
>  tools/perf/tests/builtin-test.c |   6 +++
>  tools/perf/tests/llvm.c         | 104 +++++++++++++++++++++++++++++++++++-----
>  tools/perf/tests/llvm.h         |  14 ++++++
>  tools/perf/tests/tests.h        |   4 ++
>  5 files changed, 123 insertions(+), 14 deletions(-)
>  create mode 100644 tools/perf/tests/llvm.h
> 
> diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
> index 50de225..4afc8c8 100644
> --- a/tools/perf/tests/Build
> +++ b/tools/perf/tests/Build
> @@ -31,9 +31,16 @@ perf-y += sample-parsing.o
>  perf-y += parse-no-sample-id-all.o
>  perf-y += kmod-path.o
>  perf-y += thread-map.o
> -perf-y += llvm.o
> +perf-y += llvm.o llvm-src.o
>  perf-y += topology.o
>  
> +$(OUTPUT)tests/llvm-src.c: tests/bpf-script-example.c
> +	$(call rule_mkdir)
> +	$(Q)echo '#include <tests/llvm.h>' > $@
> +	$(Q)echo 'const char test_llvm__bpf_prog[] =' >> $@
> +	$(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
> +	$(Q)echo ';' >> $@
> +
>  ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64))
>  perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
>  endif
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index 66f72d3..e812a0c 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -160,6 +160,8 @@ static struct test generic_tests[] = {
>  	{
>  		.desc = "Test LLVM searching and compiling",
>  		.func = test__llvm,
> +		.prepare = test__llvm_prepare,
> +		.cleanup = test__llvm_cleanup,
>  	},
>  	{
>  		.desc = "Test topology in session",
> @@ -261,7 +263,11 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
>  		}
>  
>  		pr_debug("\n--- start ---\n");
> +		if (t->prepare)
> +			t->prepare();
>  		err = run_test(t);
> +		if (t->cleanup)
> +			t->cleanup();
>  		pr_debug("---- end ----\n%s:", t->desc);
>  
>  		switch (err) {
> diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
> index 52d5597..236bf39 100644
> --- a/tools/perf/tests/llvm.c
> +++ b/tools/perf/tests/llvm.c
> @@ -1,9 +1,13 @@
>  #include <stdio.h>
> +#include <sys/utsname.h>
>  #include <bpf/libbpf.h>
>  #include <util/llvm-utils.h>
>  #include <util/cache.h>
> +#include <util/util.h>
> +#include <sys/mman.h>
>  #include "tests.h"
>  #include "debug.h"
> +#include "llvm.h"
>  
>  static int perf_config_cb(const char *var, const char *val,
>  			  void *arg __maybe_unused)
> @@ -11,16 +15,6 @@ static int perf_config_cb(const char *var, const char *val,
>  	return perf_default_config(var, val, arg);
>  }
>  
> -/*
> - * Randomly give it a "version" section since we don't really load it
> - * into kernel
> - */
> -static const char test_bpf_prog[] =
> -	"__attribute__((section(\"do_fork\"), used)) "
> -	"int fork(void *ctx) {return 0;} "
> -	"char _license[] __attribute__((section(\"license\"), used)) = \"GPL\";"
> -	"int _version __attribute__((section(\"version\"), used)) = 0x40100;";
> -
>  #ifdef HAVE_LIBBPF_SUPPORT
>  static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
>  {
> @@ -41,12 +35,44 @@ static int test__bpf_parsing(void *obj_buf __maybe_unused,
>  }
>  #endif
>  
> +static char *
> +compose_source(void)
> +{
> +	struct utsname utsname;
> +	int version, patchlevel, sublevel, err;
> +	unsigned long version_code;
> +	char *code;
> +
> +	if (uname(&utsname))
> +		return NULL;
> +
> +	err = sscanf(utsname.release, "%d.%d.%d",
> +		     &version, &patchlevel, &sublevel);
> +	if (err != 3) {
> +		fprintf(stderr, " (Can't get kernel version from uname '%s')",
> +			utsname.release);
> +		return NULL;
> +	}
> +
> +	version_code = (version << 16) + (patchlevel << 8) + sublevel;
> +	err = asprintf(&code, "#define LINUX_VERSION_CODE 0x%08lx;\n%s",
> +		       version_code, test_llvm__bpf_prog);
> +	if (err < 0)
> +		return NULL;
> +
> +	return code;
> +}
> +
> +#define SHARED_BUF_INIT_SIZE	(1 << 20)
> +struct test_llvm__bpf_result *p_test_llvm__bpf_result;
> +
>  int test__llvm(void)
>  {
>  	char *tmpl_new, *clang_opt_new;
>  	void *obj_buf;
>  	size_t obj_buf_sz;
>  	int err, old_verbose;
> +	char *source;
>  
>  	perf_config(perf_config_cb, NULL);
>  
> @@ -73,10 +99,22 @@ int test__llvm(void)
>  	if (!llvm_param.clang_opt)
>  		llvm_param.clang_opt = strdup("");
>  
> -	err = asprintf(&tmpl_new, "echo '%s' | %s", test_bpf_prog,
> -		       llvm_param.clang_bpf_cmd_template);
> -	if (err < 0)
> +	source = compose_source();
> +	if (!source) {
> +		pr_err("Failed to compose source code\n");
> +		return -1;
> +	}
> +
> +	/* Quote __EOF__ so strings in source won't be expanded by shell */
> +	err = asprintf(&tmpl_new, "cat << '__EOF__' | %s\n%s\n__EOF__\n",
> +		       llvm_param.clang_bpf_cmd_template, source);
> +	free(source);
> +	source = NULL;
> +	if (err < 0) {
> +		pr_err("Failed to alloc new template\n");
>  		return -1;
> +	}
> +
>  	err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
>  	if (err < 0)
>  		return -1;
> @@ -93,6 +131,46 @@ int test__llvm(void)
>  	}
>  
>  	err = test__bpf_parsing(obj_buf, obj_buf_sz);
> +	if (!err && p_test_llvm__bpf_result) {
> +		if (obj_buf_sz > SHARED_BUF_INIT_SIZE) {
> +			pr_err("Resulting object too large\n");
> +		} else {
> +			p_test_llvm__bpf_result->size = obj_buf_sz;
> +			memcpy(p_test_llvm__bpf_result->object,
> +			       obj_buf, obj_buf_sz);
> +		}
> +	}
>  	free(obj_buf);
>  	return err;
>  }
> +
> +void test__llvm_prepare(void)
> +{
> +	p_test_llvm__bpf_result = mmap(NULL, SHARED_BUF_INIT_SIZE,
> +				       PROT_READ | PROT_WRITE,
> +				       MAP_SHARED | MAP_ANONYMOUS, -1, 0);
> +	if (!p_test_llvm__bpf_result)
> +		return;
> +	memset((void *)p_test_llvm__bpf_result, '\0', SHARED_BUF_INIT_SIZE);
> +}
> +
> +void test__llvm_cleanup(void)
> +{
> +	unsigned long boundary, buf_end;
> +
> +	if (!p_test_llvm__bpf_result)
> +		return;
> +	if (p_test_llvm__bpf_result->size == 0) {
> +		munmap((void *)p_test_llvm__bpf_result, SHARED_BUF_INIT_SIZE);
> +		p_test_llvm__bpf_result = NULL;
> +		return;
> +	}
> +
> +	buf_end = (unsigned long)p_test_llvm__bpf_result + SHARED_BUF_INIT_SIZE;
> +
> +	boundary = (unsigned long)(p_test_llvm__bpf_result);
> +	boundary += p_test_llvm__bpf_result->size;
> +	boundary = (boundary + (page_size - 1)) &
> +			(~((unsigned long)page_size - 1));
> +	munmap((void *)boundary, buf_end - boundary);
> +}
> diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
> new file mode 100644
> index 0000000..1e89e46
> --- /dev/null
> +++ b/tools/perf/tests/llvm.h
> @@ -0,0 +1,14 @@
> +#ifndef PERF_TEST_LLVM_H
> +#define PERF_TEST_LLVM_H
> +
> +#include <stddef.h> /* for size_t */
> +
> +struct test_llvm__bpf_result {
> +	size_t size;
> +	char object[];
> +};
> +
> +extern struct test_llvm__bpf_result *p_test_llvm__bpf_result;
> +extern const char test_llvm__bpf_prog[];
> +
> +#endif
> diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
> index c804869..a848802 100644
> --- a/tools/perf/tests/tests.h
> +++ b/tools/perf/tests/tests.h
> @@ -27,6 +27,8 @@ enum {
>  struct test {
>  	const char *desc;
>  	int (*func)(void);
> +	void (*prepare)(void);
> +	void (*cleanup)(void);
>  };
>  
>  /* Tests */
> @@ -66,6 +68,8 @@ int test__fdarray__add(void);
>  int test__kmod_path__parse(void);
>  int test__thread_map(void);
>  int test__llvm(void);
> +void test__llvm_prepare(void);
> +void test__llvm_cleanup(void);
>  int test_session_topology(void);
>  
>  #if defined(__arm__) || defined(__aarch64__)
> -- 
> 1.8.3.4

  parent reply	other threads:[~2015-10-29 22:37 UTC|newest]

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-14 12:41 [GIT PULL 00/31] perf tools: filtering events using eBPF programs Wang Nan
2015-10-14 12:41 ` [PATCH 01/31] perf tools: Make perf depend on libbpf Wang Nan
2015-10-29 12:21   ` [tip:perf/core] " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 02/31] perf ebpf: Add the libbpf glue Wang Nan
2015-10-29 12:21   ` [tip:perf/core] " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 03/31] perf tools: Enable passing bpf object file to --event Wang Nan
2015-10-20 15:12   ` Arnaldo Carvalho de Melo
2015-10-20 15:15     ` Arnaldo Carvalho de Melo
2015-10-20 15:42       ` Arnaldo Carvalho de Melo
2015-10-21  2:01         ` Wangnan (F)
2015-10-21  1:55       ` Wangnan (F)
2015-10-29 12:22   ` [tip:perf/core] " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 04/31] perf record, bpf: Create probe points for BPF programs Wang Nan
2015-10-20 19:12   ` Arnaldo Carvalho de Melo
2015-10-20 19:16     ` David Ahern
2015-10-20 19:21       ` Arnaldo Carvalho de Melo
2015-10-20 20:34     ` Arnaldo Carvalho de Melo
2015-10-21  2:27     ` Wangnan (F)
2015-10-21  3:31     ` Wangnan (F)
2015-10-21 13:28       ` Arnaldo Carvalho de Melo
2015-10-22 16:13         ` Arnaldo Carvalho de Melo
2015-10-29 12:22   ` [tip:perf/core] perf tools: " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 05/31] perf record: Load eBPF object into kernel Wang Nan
2015-10-23 16:58   ` Arnaldo Carvalho de Melo
2015-10-24  0:27     ` Arnaldo Carvalho de Melo
2015-10-26  7:18       ` Wangnan (F)
2015-10-24  1:18     ` pi3orama
2015-10-29 12:22   ` [tip:perf/core] perf tools: " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 06/31] perf tools: Collect perf_evsel in BPF object files Wang Nan
2015-10-29 12:23   ` [tip:perf/core] perf bpf: " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 07/31] perf tools: Attach eBPF program to perf event Wang Nan
2015-10-30  9:13   ` [tip:perf/core] perf bpf: Attach eBPF filter " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 08/31] perf record: Add clang options for compiling BPF scripts Wang Nan
2015-10-30  9:14   ` [tip:perf/core] " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 09/31] perf tools: Compile scriptlets to BPF objects when passing '.c' to --event Wang Nan
2015-10-14 15:45   ` Namhyung Kim
2015-10-15  2:10     ` Wangnan (F)
2015-10-29 16:25   ` Arnaldo Carvalho de Melo
2015-10-29 16:30     ` Arnaldo Carvalho de Melo
2015-10-29 22:52       ` Arnaldo Carvalho de Melo
2015-10-30  9:14   ` [tip:perf/core] " tip-bot for Wang Nan
2015-10-14 12:41 ` [PATCH 10/31] perf test: Enforce LLVM test for BPF test Wang Nan
2015-10-14 15:48   ` Namhyung Kim
2015-10-15 11:58     ` Wangnan (F)
2015-11-03 18:24       ` Arnaldo Carvalho de Melo
2015-11-04  1:41         ` Wangnan (F)
2015-10-29 22:37   ` Arnaldo Carvalho de Melo [this message]
2015-10-31  5:31     ` Wangnan (F)
2015-10-14 12:41 ` [PATCH 11/31] perf test: Add 'perf test BPF' Wang Nan
2015-10-14 12:41 ` [PATCH 12/31] perf probe: Reset args and nargs for probe_trace_event when failure Wang Nan
2015-10-29 22:39   ` Arnaldo Carvalho de Melo
2015-10-30 10:24   ` 平松雅巳 / HIRAMATU,MASAMI
2015-10-14 12:41 ` [PATCH 13/31] bpf tools: Load a program with different instances using preprocessor Wang Nan
2015-10-29 22:44   ` Arnaldo Carvalho de Melo
2015-10-31 10:40     ` Wangnan (F)
2015-10-14 12:41 ` [PATCH 14/31] perf tools: Add BPF_PROLOGUE config options for further patches Wang Nan
2015-10-29 22:45   ` Arnaldo Carvalho de Melo
2015-10-14 12:41 ` [PATCH 15/31] perf tools: Compile dwarf-regs.c if CONFIG_BPF_PROLOGUE is on Wang Nan
2015-10-14 12:41 ` [PATCH 16/31] perf tools: Add prologue for BPF programs for fetching arguments Wang Nan
2015-10-15  5:26   ` Namhyung Kim
2015-10-15 11:56     ` Wangnan (F)
2015-10-14 12:41 ` [PATCH 17/31] perf tools: Generate prologue for BPF programs Wang Nan
2015-10-14 12:41 ` [PATCH 18/31] perf tools: Use same BPF program if arguments are identical Wang Nan
2015-10-14 12:41 ` [PATCH 19/31] perf record: Support custom vmlinux path Wang Nan
2015-10-14 12:41 ` [PATCH 20/31] perf tools: Allow BPF program attach to uprobe events Wang Nan
2015-10-27  2:28   ` Wangnan (F)
2015-10-27  3:07     ` [PATCH] perf tools: Allow BPF program attach to modules Wang Nan
2015-10-14 12:41 ` [PATCH 21/31] perf test: Enforce LLVM test, add kbuild test Wang Nan
2015-10-19 14:42   ` Namhyung Kim
2015-10-19 14:53     ` Arnaldo Carvalho de Melo
2015-10-19 15:21       ` Namhyung Kim
2015-10-20 10:36       ` Wangnan (F)
2015-10-20 13:42         ` Arnaldo Carvalho de Melo
2015-10-20 12:06       ` Wangnan (F)
2015-10-20 13:41         ` Arnaldo Carvalho de Melo
2015-10-14 12:41 ` [PATCH 22/31] perf test: Test BPF prologue Wang Nan
2015-10-14 12:41 ` [PATCH 23/31] bpf tools: Add helper function for updating bpf maps elements Wang Nan
2015-10-14 12:41 ` [PATCH 24/31] bpf tools: Collect map definition in bpf_object Wang Nan
2015-10-14 12:41 ` [PATCH 25/31] bpf tools: Extract and collect map names from BPF object file Wang Nan
2015-10-14 12:41 ` [PATCH 26/31] perf tools: Support perf event alias name Wang Nan
2015-10-21  8:53   ` Namhyung Kim
2015-10-21 13:00     ` Wangnan (F)
2015-10-22  7:16       ` Namhyung Kim
2015-10-22  7:29         ` Wangnan (F)
2015-10-22  7:53           ` Namhyung Kim
2015-10-22  7:59             ` Wangnan (F)
2015-10-14 12:41 ` [PATCH 27/31] perf tools: Pass available CPU number to clang compiler Wang Nan
2015-10-14 12:41 ` [PATCH 28/31] perf tools: Add API to config maps in bpf object Wang Nan
2015-10-14 12:41 ` [PATCH 29/31] perf tools: Add API to apply config to BPF map Wang Nan
2015-10-14 12:41 ` [PATCH 30/31] perf record: Apply config to BPF objects before recording Wang Nan
2015-10-14 12:41 ` [PATCH 31/31] perf tools: Enable BPF object configure syntax Wang Nan
2015-10-14 15:44 ` [GIT PULL 00/31] perf tools: filtering events using eBPF programs Namhyung Kim

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=20151029223744.GK2923@kernel.org \
    --to=acme@kernel.org \
    --cc=a.p.zijlstra@chello.nl \
    --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=namhyung@kernel.org \
    --cc=paulus@samba.org \
    --cc=pi3orama@163.com \
    --cc=wangnan0@huawei.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;
as well as URLs for NNTP newsgroup(s).