Message ID | 20200313075442.4071486-5-andriin@fb.com |
---|---|
State | Changes Requested |
Delegated to: | BPF Maintainers |
Headers | show |
Series | CO-RE candidate matching fix and tracing test | expand |
On Fri, Mar 13, 2020 at 12:54:41AM -0700, Andrii Nakryiko wrote: > Add vmlinux.h generation to selftest/bpf's Makefile. Use it from newly added > test_vmlinux to trace nanosleep syscall using 5 different types of programs: > - tracepoint; > - raw tracepoint; > - raw tracepoint w/ direct memory reads (tp_btf); > - kprobe; > - fentry. > > These programs are realistic variants of real-life tracing programs, > excercising vmlinux.h's usage with tracing applications. > > Signed-off-by: Andrii Nakryiko <andriin@fb.com> > --- [ ... ] > diff --git a/tools/testing/selftests/bpf/prog_tests/vmlinux.c b/tools/testing/selftests/bpf/prog_tests/vmlinux.c > new file mode 100644 > index 000000000000..04939eda1325 > --- /dev/null > +++ b/tools/testing/selftests/bpf/prog_tests/vmlinux.c > @@ -0,0 +1,43 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright (c) 2020 Facebook */ > + > +#include <test_progs.h> > +#include <time.h> > +#include "test_vmlinux.skel.h" > + > +#define MY_TV_NSEC 1337 > + > +static void nsleep() > +{ > + struct timespec ts = { .tv_nsec = MY_TV_NSEC }; > + > + (void)nanosleep(&ts, NULL); > +} > + > +void test_vmlinux(void) > +{ > + int duration = 0, err; > + struct test_vmlinux* skel; > + struct test_vmlinux__bss *bss; > + > + skel = test_vmlinux__open_and_load(); > + if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) > + return; > + bss = skel->bss; > + > + err = test_vmlinux__attach(skel); > + if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) > + goto cleanup; > + > + /* trigger everything */ > + nsleep(); > + > + CHECK(!bss->tp_called, "tp", "not called\n"); > + CHECK(!bss->raw_tp_called, "raw_tp", "not called\n"); > + CHECK(!bss->tp_btf_called, "tp_btf", "not called\n"); > + CHECK(!bss->kprobe_called, "kprobe", "not called\n"); > + CHECK(!bss->fentry_called, "fentry", "not called\n"); > + > +cleanup: > + test_vmlinux__destroy(skel); > +} > diff --git a/tools/testing/selftests/bpf/progs/test_vmlinux.c b/tools/testing/selftests/bpf/progs/test_vmlinux.c > new file mode 100644 > index 000000000000..5cc2bf8011b0 > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/test_vmlinux.c > @@ -0,0 +1,98 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright (c) 2020 Facebook */ > + > +#include "vmlinux.h" > +#include <asm/unistd.h> > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_tracing.h> > +#include <bpf/bpf_core_read.h> > + > +#define MY_TV_NSEC 1337 > + > +bool tp_called = false; > +bool raw_tp_called = false; > +bool tp_btf_called = false; > +bool kprobe_called = false; > +bool fentry_called = false; > + > +SEC("tp/syscalls/sys_enter_nanosleep") > +int handle__tp(struct trace_event_raw_sys_enter *args) > +{ > + struct __kernel_timespec *ts; > + > + if (args->id != __NR_nanosleep) > + return 0; > + > + ts = (void *)args->args[0]; > + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC) > + return 0; > + > + tp_called = true; > + return 0; > +} > + > +static bool __always_inline handle_probed(struct pt_regs *regs, long id) It is not used, may be removing it? > +{ > + struct __kernel_timespec *ts; > + > + if (id != __NR_nanosleep) > + return false; > + > + ts = (void *)PT_REGS_PARM1_CORE(regs); > + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC) > + return false; > + > + return true; > +}
On Fri, Mar 13, 2020 at 10:02 AM Martin KaFai Lau <kafai@fb.com> wrote: > > On Fri, Mar 13, 2020 at 12:54:41AM -0700, Andrii Nakryiko wrote: > > Add vmlinux.h generation to selftest/bpf's Makefile. Use it from newly added > > test_vmlinux to trace nanosleep syscall using 5 different types of programs: > > - tracepoint; > > - raw tracepoint; > > - raw tracepoint w/ direct memory reads (tp_btf); > > - kprobe; > > - fentry. > > > > These programs are realistic variants of real-life tracing programs, > > excercising vmlinux.h's usage with tracing applications. > > > > Signed-off-by: Andrii Nakryiko <andriin@fb.com> > > --- > [ ... ] > > > diff --git a/tools/testing/selftests/bpf/prog_tests/vmlinux.c b/tools/testing/selftests/bpf/prog_tests/vmlinux.c > > new file mode 100644 > > index 000000000000..04939eda1325 > > --- /dev/null > > +++ b/tools/testing/selftests/bpf/prog_tests/vmlinux.c > > @@ -0,0 +1,43 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* Copyright (c) 2020 Facebook */ > > + > > +#include <test_progs.h> > > +#include <time.h> > > +#include "test_vmlinux.skel.h" > > + > > +#define MY_TV_NSEC 1337 > > + > > +static void nsleep() > > +{ > > + struct timespec ts = { .tv_nsec = MY_TV_NSEC }; > > + > > + (void)nanosleep(&ts, NULL); > > +} > > + > > +void test_vmlinux(void) > > +{ > > + int duration = 0, err; > > + struct test_vmlinux* skel; > > + struct test_vmlinux__bss *bss; > > + > > + skel = test_vmlinux__open_and_load(); > > + if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) > > + return; > > + bss = skel->bss; > > + > > + err = test_vmlinux__attach(skel); > > + if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) > > + goto cleanup; > > + > > + /* trigger everything */ > > + nsleep(); > > + > > + CHECK(!bss->tp_called, "tp", "not called\n"); > > + CHECK(!bss->raw_tp_called, "raw_tp", "not called\n"); > > + CHECK(!bss->tp_btf_called, "tp_btf", "not called\n"); > > + CHECK(!bss->kprobe_called, "kprobe", "not called\n"); > > + CHECK(!bss->fentry_called, "fentry", "not called\n"); > > + > > +cleanup: > > + test_vmlinux__destroy(skel); > > +} > > diff --git a/tools/testing/selftests/bpf/progs/test_vmlinux.c b/tools/testing/selftests/bpf/progs/test_vmlinux.c > > new file mode 100644 > > index 000000000000..5cc2bf8011b0 > > --- /dev/null > > +++ b/tools/testing/selftests/bpf/progs/test_vmlinux.c > > @@ -0,0 +1,98 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* Copyright (c) 2020 Facebook */ > > + > > +#include "vmlinux.h" > > +#include <asm/unistd.h> > > +#include <bpf/bpf_helpers.h> > > +#include <bpf/bpf_tracing.h> > > +#include <bpf/bpf_core_read.h> > > + > > +#define MY_TV_NSEC 1337 > > + > > +bool tp_called = false; > > +bool raw_tp_called = false; > > +bool tp_btf_called = false; > > +bool kprobe_called = false; > > +bool fentry_called = false; > > + > > +SEC("tp/syscalls/sys_enter_nanosleep") > > +int handle__tp(struct trace_event_raw_sys_enter *args) > > +{ > > + struct __kernel_timespec *ts; > > + > > + if (args->id != __NR_nanosleep) > > + return 0; > > + > > + ts = (void *)args->args[0]; > > + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC) > > + return 0; > > + > > + tp_called = true; > > + return 0; > > +} > > + > > +static bool __always_inline handle_probed(struct pt_regs *regs, long id) > It is not used, may be removing it? > Oh, did I really leave it around?... Sigh, will post v2 without it. > > +{ > > + struct __kernel_timespec *ts; > > + > > + if (id != __NR_nanosleep) > > + return false; > > + > > + ts = (void *)PT_REGS_PARM1_CORE(regs); > > + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC) > > + return false; > > + > > + return true; > > +}
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index da4389dde9f7..3bbda8eb57aa 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -135,7 +135,7 @@ VMLINUX_BTF_PATHS := $(if $(O),$(O)/vmlinux) \ ../../../../vmlinux \ /sys/kernel/btf/vmlinux \ /boot/vmlinux-$(shell uname -r) -VMLINUX_BTF:= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) +VMLINUX_BTF := $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) $(OUTPUT)/runqslower: $(BPFOBJ) $(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/runqslower \ @@ -176,6 +176,10 @@ $(BUILD_DIR)/libbpf $(BUILD_DIR)/bpftool $(INCLUDE_DIR): $(call msg,MKDIR,,$@) mkdir -p $@ +$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) | $(BPFTOOL) $(INCLUDE_DIR) + $(call msg,GEN,,$@) + $(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ + # Get Clang's default includes on this system, as opposed to those seen by # '-target bpf'. This fixes "missing" files on some architectures/distros, # such as asm/byteorder.h, asm/socket.h, asm/sockios.h, sys/cdefs.h etc. @@ -284,6 +288,7 @@ $(TRUNNER_BPF_PROGS_DIR)$(if $2,-)$2-bpfobjs := y $(TRUNNER_BPF_OBJS): $(TRUNNER_OUTPUT)/%.o: \ $(TRUNNER_BPF_PROGS_DIR)/%.c \ $(TRUNNER_BPF_PROGS_DIR)/*.h \ + $$(INCLUDE_DIR)/vmlinux.h \ $$(BPFOBJ) | $(TRUNNER_OUTPUT) $$(call $(TRUNNER_BPF_BUILD_RULE),$$<,$$@, \ $(TRUNNER_BPF_CFLAGS), \ diff --git a/tools/testing/selftests/bpf/prog_tests/vmlinux.c b/tools/testing/selftests/bpf/prog_tests/vmlinux.c new file mode 100644 index 000000000000..04939eda1325 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/vmlinux.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Facebook */ + +#include <test_progs.h> +#include <time.h> +#include "test_vmlinux.skel.h" + +#define MY_TV_NSEC 1337 + +static void nsleep() +{ + struct timespec ts = { .tv_nsec = MY_TV_NSEC }; + + (void)nanosleep(&ts, NULL); +} + +void test_vmlinux(void) +{ + int duration = 0, err; + struct test_vmlinux* skel; + struct test_vmlinux__bss *bss; + + skel = test_vmlinux__open_and_load(); + if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) + return; + bss = skel->bss; + + err = test_vmlinux__attach(skel); + if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) + goto cleanup; + + /* trigger everything */ + nsleep(); + + CHECK(!bss->tp_called, "tp", "not called\n"); + CHECK(!bss->raw_tp_called, "raw_tp", "not called\n"); + CHECK(!bss->tp_btf_called, "tp_btf", "not called\n"); + CHECK(!bss->kprobe_called, "kprobe", "not called\n"); + CHECK(!bss->fentry_called, "fentry", "not called\n"); + +cleanup: + test_vmlinux__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/test_vmlinux.c b/tools/testing/selftests/bpf/progs/test_vmlinux.c new file mode 100644 index 000000000000..5cc2bf8011b0 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_vmlinux.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Facebook */ + +#include "vmlinux.h" +#include <asm/unistd.h> +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> +#include <bpf/bpf_core_read.h> + +#define MY_TV_NSEC 1337 + +bool tp_called = false; +bool raw_tp_called = false; +bool tp_btf_called = false; +bool kprobe_called = false; +bool fentry_called = false; + +SEC("tp/syscalls/sys_enter_nanosleep") +int handle__tp(struct trace_event_raw_sys_enter *args) +{ + struct __kernel_timespec *ts; + + if (args->id != __NR_nanosleep) + return 0; + + ts = (void *)args->args[0]; + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC) + return 0; + + tp_called = true; + return 0; +} + +static bool __always_inline handle_probed(struct pt_regs *regs, long id) +{ + struct __kernel_timespec *ts; + + if (id != __NR_nanosleep) + return false; + + ts = (void *)PT_REGS_PARM1_CORE(regs); + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC) + return false; + + return true; +} + +SEC("raw_tp/sys_enter") +int BPF_PROG(handle__raw_tp, struct pt_regs *regs, long id) +{ + struct __kernel_timespec *ts; + + if (id != __NR_nanosleep) + return 0; + + ts = (void *)PT_REGS_PARM1_CORE(regs); + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC) + return 0; + + raw_tp_called = true; + return 0; +} + +SEC("tp_btf/sys_enter") +int BPF_PROG(handle__tp_btf, struct pt_regs *regs, long id) +{ + struct __kernel_timespec *ts; + + if (id != __NR_nanosleep) + return 0; + + ts = (void *)PT_REGS_PARM1_CORE(regs); + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC) + return 0; + + tp_btf_called = true; + return 0; +} + +SEC("kprobe/hrtimer_nanosleep") +int BPF_KPROBE(handle__kprobe, + ktime_t rqtp, enum hrtimer_mode mode, clockid_t clockid) +{ + if (rqtp == MY_TV_NSEC) + kprobe_called = true; + return 0; +} + +SEC("fentry/hrtimer_nanosleep") +int BPF_PROG(handle__fentry, + ktime_t rqtp, enum hrtimer_mode mode, clockid_t clockid) +{ + if (rqtp == MY_TV_NSEC) + fentry_called = true; + return 0; +} + +char _license[] SEC("license") = "GPL";
Add vmlinux.h generation to selftest/bpf's Makefile. Use it from newly added test_vmlinux to trace nanosleep syscall using 5 different types of programs: - tracepoint; - raw tracepoint; - raw tracepoint w/ direct memory reads (tp_btf); - kprobe; - fentry. These programs are realistic variants of real-life tracing programs, excercising vmlinux.h's usage with tracing applications. Signed-off-by: Andrii Nakryiko <andriin@fb.com> --- tools/testing/selftests/bpf/Makefile | 7 +- .../selftests/bpf/prog_tests/vmlinux.c | 43 ++++++++ .../selftests/bpf/progs/test_vmlinux.c | 98 +++++++++++++++++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/vmlinux.c create mode 100644 tools/testing/selftests/bpf/progs/test_vmlinux.c