On Wed, Dec 22, 2021 at 2:17 PM Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> wrote: > > On Wed, Dec 22, 2021 at 5:44 AM Jiri Olsa <jolsa@xxxxxxxxxx> wrote: > > > > On Tue, Dec 21, 2021 at 01:58:14PM -0800, Andrii Nakryiko wrote: > > > On Tue, Dec 21, 2021 at 12:23 AM Jiri Olsa <jolsa@xxxxxxxxxx> wrote: > > > > > > > > On Thu, Dec 16, 2021 at 02:21:08PM -0800, Christy Lee wrote: > > > > > bpf__object_next is deprecated, track bpf_objects directly in > > > > > perf instead. > > > > > > > > > > Signed-off-by: Christy Lee <christylee@xxxxxx> > > > > > Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > > > > > --- > > > > > tools/perf/util/bpf-loader.c | 72 +++++++++++++++++++++++++++--------- > > > > > tools/perf/util/bpf-loader.h | 1 + > > > > > 2 files changed, 55 insertions(+), 18 deletions(-) > > > > > > > > > > diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c > > > > > index 528aeb0ab79d..9e3988fd719a 100644 > > > > > --- a/tools/perf/util/bpf-loader.c > > > > > +++ b/tools/perf/util/bpf-loader.c > > > > > @@ -29,9 +29,6 @@ > > > > > > > > > > #include <internal/xyarray.h> > > > > > > > > > > -/* temporarily disable libbpf deprecation warnings */ > > > > > -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" > > > > > - > > > > > static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)), > > > > > const char *fmt, va_list args) > > > > > { > > > > > @@ -49,6 +46,36 @@ struct bpf_prog_priv { > > > > > int *type_mapping; > > > > > }; > > > > > > > > > > +struct bpf_perf_object { > > > > > + struct bpf_object *obj; > > > > > + struct list_head list; > > > > > +}; > > > > > + > > > > > +static LIST_HEAD(bpf_objects_list); > > > > > > > > hum, so this duplicates libbpf's bpf_objects_list, > > > > how do objects get on this list? > > > > > > yep, this list needs to be updated on perf side each time > > > bpf_object__open() (and any variant of open) is called. > > > > > > > > > > > could you please put more comments in changelog > > > > and share how you tested this? > > > > > > I actually have no idea how to test this as well, can you please share > > > some ideas? > > > > > > > I don't use it, I just know it's there.. that's why I asked ;-) > > > > it's possible to specify bpf program on the perf command line > > to be attached to event, like: > > > > # cat tools/perf/examples/bpf/hello.c > > #include <stdio.h> > > > > int syscall_enter(openat)(void *args) > > { > > puts("Hello, world\n"); > > return 0; > > } > > > > license(GPL); > > # > > # perf trace -e openat,tools/perf/examples/bpf/hello.c cat /etc/passwd > /dev/null > > 0.016 ( ): __bpf_stdout__:Hello, world > > 0.018 ( 0.010 ms): cat/9079 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC) = 3 > > 0.057 ( ): __bpf_stdout__:Hello, world > > 0.059 ( 0.011 ms): cat/9079 openat(dfd: CWD, filename: /lib64/libc.so.6, flags: CLOEXEC) = 3 > > 0.417 ( ): __bpf_stdout__:Hello, world > > 0.419 ( 0.009 ms): cat/9079 openat(dfd: CWD, filename: /etc/passwd) = 3 > > # > > > > I took that example from commit message [...] I found the original commit aa3abf30bb28addcf593578d37447d42e3f65fc3 that included a test case, but I'm having trouble reproducing it due to syntax error. I am running this on bpf-next master without my patches. I ran 'perf test -v LLVM' and used it's output to generate a script for compiling the perf test object: -------------------------------------------------- $ cat ~/bin/hello-ebpf INPUT_FILE=/tmp/test.c OUTPUT_FILE=/tmp/test.o export KBUILD_DIR=/lib/modules/5.12.0-0_fbk2_3390_g7ecb4ac46d7f/build export NR_CPUS=56 export LINUX_VERSION_CODE=0x50c00 export CLANG_EXEC=/data/users/christylee/devtools/llvm/latest/bin/clang export CLANG_OPTIONS=-xc export KERNEL_INC_OPTIONS="-nostdinc -isystem /data/users/christylee/devtools/gcc/10.3.0/lib/gcc/x86_64-pc-linux-gnu/10.3.0/include -I./arch/\ x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./in\ clude/generated/uapi -include ./include/linux/compiler-version.h -include ./include/linux/kconfig.h" export PERF_BPF_INC_OPTIONS=-I/home/christylee/lib/perf/include/bpf export WORKING_DIR=/lib/modules/5.12.0-0_fbk2_3390_g7ecb4ac46d7f/build export CLANG_SOURCE=- rm -f $OUTPUT_FILE cat $INPUT_FILE | /data/users/christylee/devtools/llvm/latest/bin/clang -D__KERNEL__ -D__NR_CPUS__=56 -DLINUX_VERSION_CODE=0x50c00 -xc -I/ho\ me/christylee/lib/perf/include/bpf -nostdinc -isystem /data/users/christylee/devtools/gcc/10.3.0/lib/gcc/x86_64-pc-linux-gnu/10.3.0/include \ -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/ua\ pi -I./include/generated/uapi -include ./include/linux/compiler-version.h -include ./include/linux/kconfig.h -Wno-unused-value -Wno-pointer-\ sign -working-directory /lib/modules/5.12.0-0_fbk2_3390_g7ecb4ac46d7f/build -c - -target bpf -O2 -o $OUTPUT_FILE -------------------------------------------------- I then wrote and compiled a script that ask to get asks to put a probe at a function that does not exists in the kernel, it errors out as expected: $ cat /tmp/test.c __attribute__((section("fork=does_not_exist"), used)) int fork(void *ctx) { return 0; } char _license[] __attribute__((section("license"), used)) = "GPL"; int _version __attribute__((section("version"), used)) = 0x40100; $ cd ~/bin && ./hello-ebpf $ perf record --event /tmp/test.o sleep 1 Using perf wrapper that supports hot-text. Try perf.real if you encounter any issues. Probe point 'does_not_exist' not found. event syntax error: '/tmp/test.o' \___ You need to check probing points in BPF file (add -v to see detail) Run 'perf list' for a list of valid events Usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] -e, --event <event> event selector. use 'perf list' to list available events --------------------------------------------------- Next I changed the attribute to something that exists in the kernel. As expected, it errors out with permission problem: $ cat /tmp/test.c __attribute__((section("fork=fork_init"), used)) int fork(void *ctx) { return 0; } char _license[] __attribute__((section("license"), used)) = "GPL"; int _version __attribute__((section("version"), used)) = 0x40100; $ grep fork_init /proc/kallsyms ffffffff8146e250 T xfs_ifork_init_cow ffffffff83980481 T fork_init $ cd ~/bin && ./hello-ebpf $ perf record --event /tmp/test.o sleep 1 Using perf wrapper that supports hot-text. Try perf.real if you encounter any issues. Failed to open kprobe_events: Permission denied event syntax error: '/tmp/test.o' \___ You need to be root (add -v to see detail) Run 'perf list' for a list of valid events Usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] -e, --event <event> event selector. use 'perf list' to list available events --------------------------------------------------- So I reran as root, but this time I get an invalid syntax error: # perf record --event /tmp/test.o -v sleep 1 Using perf wrapper that supports hot-text. Try perf.real if you encounter any issues. Failed to write event: Invalid argument event syntax error: '/tmp/test.o' \___ Invalid argument (add -v to see detail) Run 'perf list' for a list of valid events Usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] -e, --event <event> event selector. use 'perf list' to list available events --------------------------------------------------- Is there a different way to attach a custom event probe point?