Re: [PATCH 12/13] perf test: Test BPF prologue
From: Arnaldo Carvalho de Melo
Date: Mon Nov 16 2015 - 20:29:41 EST
Em Mon, Nov 16, 2015 at 12:10:14PM +0000, Wang Nan escreveu:
> This patch introduces a new BPF script to test BPF prologue. The new
> script probes at null_lseek, which is the function pointer when we try
> to lseek on '/dev/null'.
>
> null_lseek is chosen because it is a function pointer, so we don't need
> to consider inlining and LTO.
>
> By extracting file->f_mode, bpf-script-test-prologue.c should know whether
> the file is writable or readonly. According to llseek_loop() and
> bpf-script-test-prologue.c, one forth of total lseeks should be collected.
So I tentatively changed the section name key=val separator from '\n' to
';', applied all the patches up to this one (will review the last one
tomorrow), and tested it, reproducing your results, for some reason that
SEC() wasn't working, have to check again, using it expanded, as in my
previous tests, works, I updated the comments to reflect the tests I
did, please take a look.
I've pushed everything to my perf/ebpf branch, please let me know if
what is there is acceptable, then it will be up to Ingo to decide where
to put this, if in perf/urgent for this merge window, or in perf/core,
for the next one.
Ah, to extract the output for these BPF sub-tests I had to use -v, i.e.
just:
# perf test BPF
37: Test BPF filter : Ok
#
Ditto for the LLVM one.
Doesn't tell us too much about all those nice sub-tests...
How about:
# perf test -v BPF
37: Test BPF filter:
37.1: test a : Ok
37.2: test b : Ok
37.3: Test BPF prologue generation : Ok
37.4: Another... : Ok
37: Test BPF filter : Ok
#
Thanks!
- Arnaldo
> Signed-off-by: Wang Nan <wangnan0@xxxxxxxxxx>
> Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
> Cc: Alexei Starovoitov <ast@xxxxxxxxxx>
> Cc: Masami Hiramatsu <masami.hiramatsu.pt@xxxxxxxxxxx>
> Cc: Zefan Li <lizefan@xxxxxxxxxx>
> Cc: pi3orama@xxxxxxx
> ---
> tools/perf/tests/Build | 9 +++++++-
> tools/perf/tests/bpf-script-test-prologue.c | 35 +++++++++++++++++++++++++++++
> tools/perf/tests/bpf.c | 34 ++++++++++++++++++++++++++++
> tools/perf/tests/llvm.c | 4 ++++
> tools/perf/tests/llvm.h | 2 ++
> 5 files changed, 83 insertions(+), 1 deletion(-)
> create mode 100644 tools/perf/tests/bpf-script-test-prologue.c
>
> diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
> index f41ebf8..0ff8a97 100644
> --- a/tools/perf/tests/Build
> +++ b/tools/perf/tests/Build
> @@ -31,7 +31,7 @@ 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 llvm-src-base.o llvm-src-kbuild.o
> +perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o
> perf-y += bpf.o
> perf-y += topology.o
>
> @@ -49,6 +49,13 @@ $(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c
> $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
> $(Q)echo ';' >> $@
>
> +$(OUTPUT)tests/llvm-src-prologue.c: tests/bpf-script-test-prologue.c
> + $(call rule_mkdir)
> + $(Q)echo '#include <tests/llvm.h>' > $@
> + $(Q)echo 'const char test_llvm__bpf_test_prologue_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/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c
> new file mode 100644
> index 0000000..7230e62
> --- /dev/null
> +++ b/tools/perf/tests/bpf-script-test-prologue.c
> @@ -0,0 +1,35 @@
> +/*
> + * bpf-script-test-prologue.c
> + * Test BPF prologue
> + */
> +#ifndef LINUX_VERSION_CODE
> +# error Need LINUX_VERSION_CODE
> +# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
> +#endif
> +#define SEC(NAME) __attribute__((section(NAME), used))
> +
> +#include <uapi/linux/fs.h>
> +
> +#define FMODE_READ 0x1
> +#define FMODE_WRITE 0x2
> +
> +static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =
> + (void *) 6;
> +
> +SEC("func=null_lseek file->f_mode offset orig")
> +int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode,
> + unsigned long offset, unsigned long orig)
> +{
> + if (err)
> + return 0;
> + if (f_mode & FMODE_WRITE)
> + return 0;
> + if (offset & 1)
> + return 0;
> + if (orig == SEEK_CUR)
> + return 0;
> + return 1;
> +}
> +
> +char _license[] SEC("license") = "GPL";
> +int _version SEC("version") = LINUX_VERSION_CODE;
> diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
> index ec16f78..c7131fa 100644
> --- a/tools/perf/tests/bpf.c
> +++ b/tools/perf/tests/bpf.c
> @@ -19,6 +19,29 @@ static int epoll_pwait_loop(void)
> return 0;
> }
>
> +#ifdef HAVE_BPF_PROLOGUE
> +
> +static int llseek_loop(void)
> +{
> + int fds[2], i;
> +
> + fds[0] = open("/dev/null", O_RDONLY);
> + fds[1] = open("/dev/null", O_RDWR);
> +
> + if (fds[0] < 0 || fds[1] < 0)
> + return -1;
> +
> + for (i = 0; i < NR_ITERS; i++) {
> + lseek(fds[i % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
> + lseek(fds[(i + 1) % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
> + }
> + close(fds[0]);
> + close(fds[1]);
> + return 0;
> +}
> +
> +#endif
> +
> static struct {
> enum test_llvm__testcase prog_id;
> const char *desc;
> @@ -37,6 +60,17 @@ static struct {
> &epoll_pwait_loop,
> (NR_ITERS + 1) / 2,
> },
> +#ifdef HAVE_BPF_PROLOGUE
> + {
> + LLVM_TESTCASE_BPF_PROLOGUE,
> + "Test BPF prologue generation",
> + "[bpf_prologue_test]",
> + "fix kbuild first",
> + "check your vmlinux setting?",
> + &llseek_loop,
> + (NR_ITERS + 1) / 4,
> + },
> +#endif
> };
>
> static int do_test(struct bpf_object *obj, int (*func)(void),
> diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
> index bc4cf50..7f4f7f7 100644
> --- a/tools/perf/tests/llvm.c
> +++ b/tools/perf/tests/llvm.c
> @@ -44,6 +44,10 @@ static struct {
> .source = test_llvm__bpf_test_kbuild_prog,
> .desc = "Test kbuild searching",
> },
> + [LLVM_TESTCASE_BPF_PROLOGUE] = {
> + .source = test_llvm__bpf_test_prologue_prog,
> + .desc = "Test BPF prologue generation",
> + },
> };
>
>
> diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
> index d91d8f4..5150b4d 100644
> --- a/tools/perf/tests/llvm.h
> +++ b/tools/perf/tests/llvm.h
> @@ -6,10 +6,12 @@
>
> extern const char test_llvm__bpf_base_prog[];
> extern const char test_llvm__bpf_test_kbuild_prog[];
> +extern const char test_llvm__bpf_test_prologue_prog[];
>
> enum test_llvm__testcase {
> LLVM_TESTCASE_BASE,
> LLVM_TESTCASE_KBUILD,
> + LLVM_TESTCASE_BPF_PROLOGUE,
> __LLVM_TESTCASE_MAX,
> };
>
> --
> 1.8.3.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/