Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf parse-events: Remove BPF event support

New features like the BPF --filter support in perf record have made the
BPF event functionality somewhat redundant. As shown by commit
fcb027c1a4f6 ("perf tools: Revert enable indices setting syntax for BPF
map") and commit 14e4b9f4289a ("perf trace: Raw augmented syscalls fix
libbpf 1.0+ compatibility") the BPF event support hasn't been well
maintained and it adds considerable complexity in areas like event
parsing, not least as '/' is a separator for event modifiers as well as
in paths.

This patch removes support in the event parser for BPF events and then
the associated functions are removed. This leads to the removal of whole
source files like bpf-loader.c. Removing support means that augmented
syscalls in perf trace is broken, this will be fixed in a later commit
adding support using BPF skeletons.

The removal of BPF events causes an unused label warning from flex
generated code, so update build to ignore it:

```
util/parse-events-flex.c:2704:1: error: label ‘find_rule’ defined but not used [-Werror=unused-label]
2704 | find_rule: /* we branch to this label when backing up */
```

Committer notes:

Extracted from a larger patch that was also removing the support for
linking with libllvm and libclang, that were an alternative to using an
external clang execution to compile the .c event source code into BPF
bytecode.

Testing it:

# perf trace -e /home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c
event syntax error: '/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c'
\___ Bad event or PMU

Unabled to find PMU or event on a PMU of 'home'

Initial error:
event syntax error: '/home/acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c'
\___ Cannot find PMU `home'. Missing kernel support?
Run 'perf list' for a list of valid events

Usage: perf trace [<options>] [<command>]
or: perf trace [<options>] -- <command> [<options>]
or: perf trace record [<options>] [<command>]
or: perf trace record [<options>] -- <command> [<options>]

-e, --event <event> event/syscall selector. use 'perf list' to list available events
#

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Carsten Haitzler <carsten.haitzler@arm.com>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Fangrui Song <maskray@google.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Tom Rix <trix@redhat.com>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: Wang ShaoBo <bobo.shaobowang@huawei.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: Yonghong Song <yhs@fb.com>
Cc: YueHaibing <yuehaibing@huawei.com>
Cc: bpf@vger.kernel.org
Cc: llvm@lists.linux.dev
Link: https://lore.kernel.org/r/20230810184853.2860737-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
3d6dfae8 56b11a21

+3 -4381
-33
tools/perf/Documentation/perf-config.txt
··· 125 125 group = true 126 126 skip-empty = true 127 127 128 - [llvm] 129 - dump-obj = true 130 - clang-opt = -g 131 128 132 129 You can hide source code of annotate feature setting the config to false with 133 130 ··· 653 656 Can be used to select the default tracer when neither -G nor 654 657 -F option is not specified. Possible values are 'function' and 655 658 'function_graph'. 656 - 657 - llvm.*:: 658 - llvm.clang-path:: 659 - Path to clang. If omit, search it from $PATH. 660 - 661 - llvm.clang-bpf-cmd-template:: 662 - Cmdline template. Below lines show its default value. Environment 663 - variable is used to pass options. 664 - "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\ 665 - "-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE " \ 666 - "$CLANG_OPTIONS $PERF_BPF_INC_OPTIONS $KERNEL_INC_OPTIONS " \ 667 - "-Wno-unused-value -Wno-pointer-sign " \ 668 - "-working-directory $WORKING_DIR " \ 669 - "-c \"$CLANG_SOURCE\" --target=bpf $CLANG_EMIT_LLVM -O2 -o - $LLVM_OPTIONS_PIPE" 670 - 671 - llvm.clang-opt:: 672 - Options passed to clang. 673 - 674 - llvm.kbuild-dir:: 675 - kbuild directory. If not set, use /lib/modules/`uname -r`/build. 676 - If set to "" deliberately, skip kernel header auto-detector. 677 - 678 - llvm.kbuild-opts:: 679 - Options passed to 'make' when detecting kernel header options. 680 - 681 - llvm.dump-obj:: 682 - Enable perf dump BPF object files compiled by LLVM. 683 - 684 - llvm.opts:: 685 - Options passed to llc. 686 659 687 660 samples.*:: 688 661
-22
tools/perf/Documentation/perf-record.txt
··· 99 99 If you want to profile write accesses in [0x1000~1008), just set 100 100 'mem:0x1000/8:w'. 101 101 102 - - a BPF source file (ending in .c) or a precompiled object file (ending 103 - in .o) selects one or more BPF events. 104 - The BPF program can attach to various perf events based on the ELF section 105 - names. 106 - 107 - When processing a '.c' file, perf searches an installed LLVM to compile it 108 - into an object file first. Optional clang options can be passed via the 109 - '--clang-opt' command line option, e.g.: 110 - 111 - perf record --clang-opt "-DLINUX_VERSION_CODE=0x50000" \ 112 - -e tests/bpf-script-example.c 113 - 114 - Note: '--clang-opt' must be placed before '--event/-e'. 115 - 116 102 - a group of events surrounded by a pair of brace ("{event1,event2,...}"). 117 103 Each event is separated by commas and the group should be quoted to 118 104 prevent the shell interpretation. You also need to use --group on ··· 532 546 PERF_RECORD_SWITCH_CPU_WIDE. In some cases (e.g. Intel PT, CoreSight or Arm SPE) 533 547 switch events will be enabled automatically, which can be suppressed by 534 548 by the option --no-switch-events. 535 - 536 - --clang-path=PATH:: 537 - Path to clang binary to use for compiling BPF scriptlets. 538 - (enabled when BPF support is on) 539 - 540 - --clang-opt=OPTIONS:: 541 - Options passed to clang when compiling BPF scriptlets. 542 - (enabled when BPF support is on) 543 549 544 550 --vmlinux=PATH:: 545 551 Specify vmlinux path which has debuginfo.
-12
tools/perf/Makefile.config
··· 589 589 LIBBPF_STATIC := 1 590 590 endif 591 591 endif 592 - 593 - ifndef NO_DWARF 594 - ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET 595 - CFLAGS += -DHAVE_BPF_PROLOGUE 596 - $(call detected,CONFIG_BPF_PROLOGUE) 597 - else 598 - msg := $(warning BPF prologue is not supported by architecture $(SRCARCH), missing regs_query_register_offset()); 599 - endif 600 - else 601 - msg := $(warning DWARF support is off, BPF prologue is disabled); 602 - endif 603 - 604 592 endif # NO_LIBBPF 605 593 endif # NO_LIBELF 606 594
-45
tools/perf/builtin-record.c
··· 37 37 #include "util/parse-branch-options.h" 38 38 #include "util/parse-regs-options.h" 39 39 #include "util/perf_api_probe.h" 40 - #include "util/llvm-utils.h" 41 - #include "util/bpf-loader.h" 42 40 #include "util/trigger.h" 43 41 #include "util/perf-hooks.h" 44 42 #include "util/cpu-set-sched.h" ··· 2463 2465 } 2464 2466 } 2465 2467 2466 - err = bpf__apply_obj_config(); 2467 - if (err) { 2468 - char errbuf[BUFSIZ]; 2469 - 2470 - bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); 2471 - pr_err("ERROR: Apply config to BPF failed: %s\n", 2472 - errbuf); 2473 - goto out_free_threads; 2474 - } 2475 - 2476 2468 /* 2477 2469 * Normally perf_session__new would do this, but it doesn't have the 2478 2470 * evlist. ··· 3474 3486 "collect kernel callchains"), 3475 3487 OPT_BOOLEAN(0, "user-callchains", &record.opts.user_callchains, 3476 3488 "collect user callchains"), 3477 - OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", 3478 - "clang binary to use for compiling BPF scriptlets"), 3479 - OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", 3480 - "options passed to clang when compiling BPF scriptlets"), 3481 3489 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, 3482 3490 "file", "vmlinux pathname"), 3483 3491 OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, ··· 3951 3967 3952 3968 setlocale(LC_ALL, ""); 3953 3969 3954 - #ifndef HAVE_LIBBPF_SUPPORT 3955 - # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c) 3956 - set_nobuild('\0', "clang-path", true); 3957 - set_nobuild('\0', "clang-opt", true); 3958 - # undef set_nobuild 3959 - #endif 3960 - 3961 - #ifndef HAVE_BPF_PROLOGUE 3962 - # if !defined (HAVE_DWARF_SUPPORT) 3963 - # define REASON "NO_DWARF=1" 3964 - # elif !defined (HAVE_LIBBPF_SUPPORT) 3965 - # define REASON "NO_LIBBPF=1" 3966 - # else 3967 - # define REASON "this architecture doesn't support BPF prologue" 3968 - # endif 3969 - # define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c) 3970 - set_nobuild('\0', "vmlinux", true); 3971 - # undef set_nobuild 3972 - # undef REASON 3973 - #endif 3974 - 3975 3970 #ifndef HAVE_BPF_SKEL 3976 3971 # define set_nobuild(s, l, m, c) set_option_nobuild(record_options, s, l, m, c) 3977 3972 set_nobuild('\0', "off-cpu", "no BUILD_BPF_SKEL=1", true); ··· 4078 4115 4079 4116 if (dry_run) 4080 4117 goto out; 4081 - 4082 - err = bpf__setup_stdout(rec->evlist); 4083 - if (err) { 4084 - bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf)); 4085 - pr_err("ERROR: Setup BPF stdout failed: %s\n", 4086 - errbuf); 4087 - goto out; 4088 - } 4089 4118 4090 4119 err = -ENOMEM; 4091 4120
+1 -145
tools/perf/builtin-trace.c
··· 18 18 #include <api/fs/tracing_path.h> 19 19 #ifdef HAVE_LIBBPF_SUPPORT 20 20 #include <bpf/bpf.h> 21 + #include <bpf/libbpf.h> 21 22 #endif 22 23 #include "util/bpf_map.h" 23 24 #include "util/rlimit.h" ··· 54 53 #include "trace/beauty/beauty.h" 55 54 #include "trace-event.h" 56 55 #include "util/parse-events.h" 57 - #include "util/bpf-loader.h" 58 56 #include "util/tracepoint.h" 59 57 #include "callchain.h" 60 58 #include "print_binary.h" ··· 3287 3287 return bpf_object__find_map_by_name(trace->bpf_obj, name); 3288 3288 } 3289 3289 3290 - static void trace__set_bpf_map_filtered_pids(struct trace *trace) 3291 - { 3292 - trace->filter_pids.map = trace__find_bpf_map_by_name(trace, "pids_filtered"); 3293 - } 3294 - 3295 - static void trace__set_bpf_map_syscalls(struct trace *trace) 3296 - { 3297 - trace->syscalls.prog_array.sys_enter = trace__find_bpf_map_by_name(trace, "syscalls_sys_enter"); 3298 - trace->syscalls.prog_array.sys_exit = trace__find_bpf_map_by_name(trace, "syscalls_sys_exit"); 3299 - } 3300 - 3301 3290 static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace, const char *name) 3302 3291 { 3303 3292 struct bpf_program *pos, *prog = NULL; ··· 3542 3553 return err; 3543 3554 } 3544 3555 3545 - static void trace__delete_augmented_syscalls(struct trace *trace) 3546 - { 3547 - struct evsel *evsel, *tmp; 3548 - 3549 - evlist__remove(trace->evlist, trace->syscalls.events.augmented); 3550 - evsel__delete(trace->syscalls.events.augmented); 3551 - trace->syscalls.events.augmented = NULL; 3552 - 3553 - evlist__for_each_entry_safe(trace->evlist, tmp, evsel) { 3554 - if (evsel->bpf_obj == trace->bpf_obj) { 3555 - evlist__remove(trace->evlist, evsel); 3556 - evsel__delete(evsel); 3557 - } 3558 - 3559 - } 3560 - 3561 - bpf_object__close(trace->bpf_obj); 3562 - trace->bpf_obj = NULL; 3563 - } 3564 3556 #else // HAVE_LIBBPF_SUPPORT 3565 3557 static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace __maybe_unused, 3566 3558 const char *name __maybe_unused) 3567 - { 3568 - return NULL; 3569 - } 3570 - 3571 - static void trace__set_bpf_map_filtered_pids(struct trace *trace __maybe_unused) 3572 - { 3573 - } 3574 - 3575 - static void trace__set_bpf_map_syscalls(struct trace *trace __maybe_unused) 3576 - { 3577 - } 3578 - 3579 - static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace __maybe_unused, 3580 - const char *name __maybe_unused) 3581 3559 { 3582 3560 return NULL; 3583 3561 } ··· 3553 3597 { 3554 3598 return 0; 3555 3599 } 3556 - 3557 - static void trace__delete_augmented_syscalls(struct trace *trace __maybe_unused) 3558 - { 3559 - } 3560 3600 #endif // HAVE_LIBBPF_SUPPORT 3561 - 3562 - static bool trace__only_augmented_syscalls_evsels(struct trace *trace) 3563 - { 3564 - struct evsel *evsel; 3565 - 3566 - evlist__for_each_entry(trace->evlist, evsel) { 3567 - if (evsel == trace->syscalls.events.augmented || 3568 - evsel->bpf_obj == trace->bpf_obj) 3569 - continue; 3570 - 3571 - return false; 3572 - } 3573 - 3574 - return true; 3575 - } 3576 3601 3577 3602 static int trace__set_ev_qualifier_filter(struct trace *trace) 3578 3603 { ··· 3917 3980 err = evlist__open(evlist); 3918 3981 if (err < 0) 3919 3982 goto out_error_open; 3920 - 3921 - err = bpf__apply_obj_config(); 3922 - if (err) { 3923 - char errbuf[BUFSIZ]; 3924 - 3925 - bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); 3926 - pr_err("ERROR: Apply config to BPF failed: %s\n", 3927 - errbuf); 3928 - goto out_error_open; 3929 - } 3930 3983 3931 3984 err = trace__set_filter_pids(trace); 3932 3985 if (err < 0) ··· 4847 4920 if ((nr_cgroups || trace.cgroup) && !trace.opts.target.system_wide) { 4848 4921 usage_with_options_msg(trace_usage, trace_options, 4849 4922 "cgroup monitoring only available in system-wide mode"); 4850 - } 4851 - 4852 - evsel = bpf__setup_output_event(trace.evlist, "__augmented_syscalls__"); 4853 - if (IS_ERR(evsel)) { 4854 - bpf__strerror_setup_output_event(trace.evlist, PTR_ERR(evsel), bf, sizeof(bf)); 4855 - pr_err("ERROR: Setup trace syscalls enter failed: %s\n", bf); 4856 - goto out; 4857 - } 4858 - 4859 - if (evsel) { 4860 - trace.syscalls.events.augmented = evsel; 4861 - 4862 - evsel = evlist__find_tracepoint_by_name(trace.evlist, "raw_syscalls:sys_enter"); 4863 - if (evsel == NULL) { 4864 - pr_err("ERROR: raw_syscalls:sys_enter not found in the augmented BPF object\n"); 4865 - goto out; 4866 - } 4867 - 4868 - if (evsel->bpf_obj == NULL) { 4869 - pr_err("ERROR: raw_syscalls:sys_enter not associated to a BPF object\n"); 4870 - goto out; 4871 - } 4872 - 4873 - trace.bpf_obj = evsel->bpf_obj; 4874 - 4875 - /* 4876 - * If we have _just_ the augmenter event but don't have a 4877 - * explicit --syscalls, then assume we want all strace-like 4878 - * syscalls: 4879 - */ 4880 - if (!trace.trace_syscalls && trace__only_augmented_syscalls_evsels(&trace)) 4881 - trace.trace_syscalls = true; 4882 - /* 4883 - * So, if we have a syscall augmenter, but trace_syscalls, aka 4884 - * strace-like syscall tracing is not set, then we need to trow 4885 - * away the augmenter, i.e. all the events that were created 4886 - * from that BPF object file. 4887 - * 4888 - * This is more to fix the current .perfconfig trace.add_events 4889 - * style of setting up the strace-like eBPF based syscall point 4890 - * payload augmenter. 4891 - * 4892 - * All this complexity will be avoided by adding an alternative 4893 - * to trace.add_events in the form of 4894 - * trace.bpf_augmented_syscalls, that will be only parsed if we 4895 - * need it. 4896 - * 4897 - * .perfconfig trace.add_events is still useful if we want, for 4898 - * instance, have msr_write.msr in some .perfconfig profile based 4899 - * 'perf trace --config determinism.profile' mode, where for some 4900 - * particular goal/workload type we want a set of events and 4901 - * output mode (with timings, etc) instead of having to add 4902 - * all via the command line. 4903 - * 4904 - * Also --config to specify an alternate .perfconfig file needs 4905 - * to be implemented. 4906 - */ 4907 - if (!trace.trace_syscalls) { 4908 - trace__delete_augmented_syscalls(&trace); 4909 - } else { 4910 - trace__set_bpf_map_filtered_pids(&trace); 4911 - trace__set_bpf_map_syscalls(&trace); 4912 - trace.syscalls.unaugmented_prog = trace__find_bpf_program_by_title(&trace, "!raw_syscalls:unaugmented"); 4913 - } 4914 - } 4915 - 4916 - err = bpf__setup_stdout(trace.evlist); 4917 - if (err) { 4918 - bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf)); 4919 - pr_err("ERROR: Setup BPF stdout failed: %s\n", bf); 4920 - goto out; 4921 4923 } 4922 4924 4923 4925 err = -1;
-2
tools/perf/perf.c
··· 18 18 #include <subcmd/run-command.h> 19 19 #include "util/parse-events.h" 20 20 #include <subcmd/parse-options.h> 21 - #include "util/bpf-loader.h" 22 21 #include "util/debug.h" 23 22 #include "util/event.h" 24 23 #include "util/util.h" // usage() ··· 323 324 perf_config__exit(); 324 325 exit_browser(status); 325 326 perf_env__exit(&perf_env); 326 - bpf__clear(); 327 327 328 328 if (status) 329 329 return status & 0xff;
-5
tools/perf/tests/.gitignore
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - llvm-src-base.c 3 - llvm-src-kbuild.c 4 - llvm-src-prologue.c 5 - llvm-src-relocation.c
-30
tools/perf/tests/Build
··· 37 37 perf-y += parse-no-sample-id-all.o 38 38 perf-y += kmod-path.o 39 39 perf-y += thread-map.o 40 - perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o llvm-src-relocation.o 41 - perf-y += bpf.o 42 40 perf-y += topology.o 43 41 perf-y += mem.o 44 42 perf-y += cpumap.o ··· 66 68 perf-y += sigtrap.o 67 69 perf-y += event_groups.o 68 70 perf-y += symbols.o 69 - 70 - $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build 71 - $(call rule_mkdir) 72 - $(Q)echo '#include <tests/llvm.h>' > $@ 73 - $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@ 74 - $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ 75 - $(Q)echo ';' >> $@ 76 - 77 - $(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c tests/Build 78 - $(call rule_mkdir) 79 - $(Q)echo '#include <tests/llvm.h>' > $@ 80 - $(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@ 81 - $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ 82 - $(Q)echo ';' >> $@ 83 - 84 - $(OUTPUT)tests/llvm-src-prologue.c: tests/bpf-script-test-prologue.c tests/Build 85 - $(call rule_mkdir) 86 - $(Q)echo '#include <tests/llvm.h>' > $@ 87 - $(Q)echo 'const char test_llvm__bpf_test_prologue_prog[] =' >> $@ 88 - $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ 89 - $(Q)echo ';' >> $@ 90 - 91 - $(OUTPUT)tests/llvm-src-relocation.c: tests/bpf-script-test-relocation.c tests/Build 92 - $(call rule_mkdir) 93 - $(Q)echo '#include <tests/llvm.h>' > $@ 94 - $(Q)echo 'const char test_llvm__bpf_test_relocation[] =' >> $@ 95 - $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ 96 - $(Q)echo ';' >> $@ 97 71 98 72 ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc)) 99 73 perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
-60
tools/perf/tests/bpf-script-example.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * bpf-script-example.c 4 - * Test basic LLVM building 5 - */ 6 - #ifndef LINUX_VERSION_CODE 7 - # error Need LINUX_VERSION_CODE 8 - # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' 9 - #endif 10 - #define BPF_ANY 0 11 - #define BPF_MAP_TYPE_ARRAY 2 12 - #define BPF_FUNC_map_lookup_elem 1 13 - #define BPF_FUNC_map_update_elem 2 14 - 15 - static void *(*bpf_map_lookup_elem)(void *map, void *key) = 16 - (void *) BPF_FUNC_map_lookup_elem; 17 - static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = 18 - (void *) BPF_FUNC_map_update_elem; 19 - 20 - /* 21 - * Following macros are taken from tools/lib/bpf/bpf_helpers.h, 22 - * and are used to create BTF defined maps. It is easier to take 23 - * 2 simple macros, than being able to include above header in 24 - * runtime. 25 - * 26 - * __uint - defines integer attribute of BTF map definition, 27 - * Such attributes are represented using a pointer to an array, 28 - * in which dimensionality of array encodes specified integer 29 - * value. 30 - * 31 - * __type - defines pointer variable with typeof(val) type for 32 - * attributes like key or value, which will be defined by the 33 - * size of the type. 34 - */ 35 - #define __uint(name, val) int (*name)[val] 36 - #define __type(name, val) typeof(val) *name 37 - 38 - #define SEC(NAME) __attribute__((section(NAME), used)) 39 - struct { 40 - __uint(type, BPF_MAP_TYPE_ARRAY); 41 - __uint(max_entries, 1); 42 - __type(key, int); 43 - __type(value, int); 44 - } flip_table SEC(".maps"); 45 - 46 - SEC("syscalls:sys_enter_epoll_pwait") 47 - int bpf_func__SyS_epoll_pwait(void *ctx) 48 - { 49 - int ind =0; 50 - int *flag = bpf_map_lookup_elem(&flip_table, &ind); 51 - int new_flag; 52 - if (!flag) 53 - return 0; 54 - /* flip flag and store back */ 55 - new_flag = !*flag; 56 - bpf_map_update_elem(&flip_table, &ind, &new_flag, BPF_ANY); 57 - return new_flag; 58 - } 59 - char _license[] SEC("license") = "GPL"; 60 - int _version SEC("version") = LINUX_VERSION_CODE;
-21
tools/perf/tests/bpf-script-test-kbuild.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * bpf-script-test-kbuild.c 4 - * Test include from kernel header 5 - */ 6 - #ifndef LINUX_VERSION_CODE 7 - # error Need LINUX_VERSION_CODE 8 - # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' 9 - #endif 10 - #define SEC(NAME) __attribute__((section(NAME), used)) 11 - 12 - #include <uapi/linux/fs.h> 13 - 14 - SEC("func=vfs_llseek") 15 - int bpf_func__vfs_llseek(void *ctx) 16 - { 17 - return 0; 18 - } 19 - 20 - char _license[] SEC("license") = "GPL"; 21 - int _version SEC("version") = LINUX_VERSION_CODE;
-49
tools/perf/tests/bpf-script-test-prologue.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * bpf-script-test-prologue.c 4 - * Test BPF prologue 5 - */ 6 - #ifndef LINUX_VERSION_CODE 7 - # error Need LINUX_VERSION_CODE 8 - # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' 9 - #endif 10 - #define SEC(NAME) __attribute__((section(NAME), used)) 11 - 12 - #include <uapi/linux/fs.h> 13 - 14 - /* 15 - * If CONFIG_PROFILE_ALL_BRANCHES is selected, 16 - * 'if' is redefined after include kernel header. 17 - * Recover 'if' for BPF object code. 18 - */ 19 - #ifdef if 20 - # undef if 21 - #endif 22 - 23 - typedef unsigned int __bitwise fmode_t; 24 - 25 - #define FMODE_READ 0x1 26 - #define FMODE_WRITE 0x2 27 - 28 - static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = 29 - (void *) 6; 30 - 31 - SEC("func=null_lseek file->f_mode offset orig") 32 - int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, 33 - unsigned long offset, unsigned long orig) 34 - { 35 - fmode_t f_mode = (fmode_t)_f_mode; 36 - 37 - if (err) 38 - return 0; 39 - if (f_mode & FMODE_WRITE) 40 - return 0; 41 - if (offset & 1) 42 - return 0; 43 - if (orig == SEEK_CUR) 44 - return 0; 45 - return 1; 46 - } 47 - 48 - char _license[] SEC("license") = "GPL"; 49 - int _version SEC("version") = LINUX_VERSION_CODE;
-51
tools/perf/tests/bpf-script-test-relocation.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * bpf-script-test-relocation.c 4 - * Test BPF loader checking relocation 5 - */ 6 - #ifndef LINUX_VERSION_CODE 7 - # error Need LINUX_VERSION_CODE 8 - # error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' 9 - #endif 10 - #define BPF_ANY 0 11 - #define BPF_MAP_TYPE_ARRAY 2 12 - #define BPF_FUNC_map_lookup_elem 1 13 - #define BPF_FUNC_map_update_elem 2 14 - 15 - static void *(*bpf_map_lookup_elem)(void *map, void *key) = 16 - (void *) BPF_FUNC_map_lookup_elem; 17 - static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = 18 - (void *) BPF_FUNC_map_update_elem; 19 - 20 - struct bpf_map_def { 21 - unsigned int type; 22 - unsigned int key_size; 23 - unsigned int value_size; 24 - unsigned int max_entries; 25 - }; 26 - 27 - #define SEC(NAME) __attribute__((section(NAME), used)) 28 - struct bpf_map_def SEC("maps") my_table = { 29 - .type = BPF_MAP_TYPE_ARRAY, 30 - .key_size = sizeof(int), 31 - .value_size = sizeof(int), 32 - .max_entries = 1, 33 - }; 34 - 35 - int this_is_a_global_val; 36 - 37 - SEC("func=sys_write") 38 - int bpf_func__sys_write(void *ctx) 39 - { 40 - int key = 0; 41 - int value = 0; 42 - 43 - /* 44 - * Incorrect relocation. Should not allow this program be 45 - * loaded into kernel. 46 - */ 47 - bpf_map_update_elem(&this_is_a_global_val, &key, &value, 0); 48 - return 0; 49 - } 50 - char _license[] SEC("license") = "GPL"; 51 - int _version SEC("version") = LINUX_VERSION_CODE;
-390
tools/perf/tests/bpf.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - #include <errno.h> 3 - #include <stdio.h> 4 - #include <stdlib.h> 5 - #include <sys/epoll.h> 6 - #include <sys/types.h> 7 - #include <sys/stat.h> 8 - #include <fcntl.h> 9 - #include <util/record.h> 10 - #include <util/util.h> 11 - #include <util/bpf-loader.h> 12 - #include <util/evlist.h> 13 - #include <linux/filter.h> 14 - #include <linux/kernel.h> 15 - #include <linux/string.h> 16 - #include <api/fs/fs.h> 17 - #include <perf/mmap.h> 18 - #include "tests.h" 19 - #include "llvm.h" 20 - #include "debug.h" 21 - #include "parse-events.h" 22 - #include "util/mmap.h" 23 - #define NR_ITERS 111 24 - #define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test" 25 - 26 - #if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 27 - #include <linux/bpf.h> 28 - #include <bpf/bpf.h> 29 - 30 - static int epoll_pwait_loop(void) 31 - { 32 - struct epoll_event events; 33 - int i; 34 - 35 - /* Should fail NR_ITERS times */ 36 - for (i = 0; i < NR_ITERS; i++) 37 - epoll_pwait(-(i + 1), &events, 0, 0, NULL); 38 - return 0; 39 - } 40 - 41 - #ifdef HAVE_BPF_PROLOGUE 42 - 43 - static int llseek_loop(void) 44 - { 45 - int fds[2], i; 46 - 47 - fds[0] = open("/dev/null", O_RDONLY); 48 - fds[1] = open("/dev/null", O_RDWR); 49 - 50 - if (fds[0] < 0 || fds[1] < 0) 51 - return -1; 52 - 53 - for (i = 0; i < NR_ITERS; i++) { 54 - lseek(fds[i % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET); 55 - lseek(fds[(i + 1) % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET); 56 - } 57 - close(fds[0]); 58 - close(fds[1]); 59 - return 0; 60 - } 61 - 62 - #endif 63 - 64 - static struct { 65 - enum test_llvm__testcase prog_id; 66 - const char *name; 67 - const char *msg_compile_fail; 68 - const char *msg_load_fail; 69 - int (*target_func)(void); 70 - int expect_result; 71 - bool pin; 72 - } bpf_testcase_table[] = { 73 - { 74 - .prog_id = LLVM_TESTCASE_BASE, 75 - .name = "[basic_bpf_test]", 76 - .msg_compile_fail = "fix 'perf test LLVM' first", 77 - .msg_load_fail = "load bpf object failed", 78 - .target_func = &epoll_pwait_loop, 79 - .expect_result = (NR_ITERS + 1) / 2, 80 - }, 81 - { 82 - .prog_id = LLVM_TESTCASE_BASE, 83 - .name = "[bpf_pinning]", 84 - .msg_compile_fail = "fix kbuild first", 85 - .msg_load_fail = "check your vmlinux setting?", 86 - .target_func = &epoll_pwait_loop, 87 - .expect_result = (NR_ITERS + 1) / 2, 88 - .pin = true, 89 - }, 90 - #ifdef HAVE_BPF_PROLOGUE 91 - { 92 - .prog_id = LLVM_TESTCASE_BPF_PROLOGUE, 93 - .name = "[bpf_prologue_test]", 94 - .msg_compile_fail = "fix kbuild first", 95 - .msg_load_fail = "check your vmlinux setting?", 96 - .target_func = &llseek_loop, 97 - .expect_result = (NR_ITERS + 1) / 4, 98 - }, 99 - #endif 100 - }; 101 - 102 - static int do_test(struct bpf_object *obj, int (*func)(void), 103 - int expect) 104 - { 105 - struct record_opts opts = { 106 - .target = { 107 - .uid = UINT_MAX, 108 - .uses_mmap = true, 109 - }, 110 - .freq = 0, 111 - .mmap_pages = 256, 112 - .default_interval = 1, 113 - }; 114 - 115 - char pid[16]; 116 - char sbuf[STRERR_BUFSIZE]; 117 - struct evlist *evlist; 118 - int i, ret = TEST_FAIL, err = 0, count = 0; 119 - 120 - struct parse_events_state parse_state; 121 - struct parse_events_error parse_error; 122 - 123 - parse_events_error__init(&parse_error); 124 - bzero(&parse_state, sizeof(parse_state)); 125 - parse_state.error = &parse_error; 126 - INIT_LIST_HEAD(&parse_state.list); 127 - 128 - err = parse_events_load_bpf_obj(&parse_state, &parse_state.list, obj, NULL, NULL); 129 - parse_events_error__exit(&parse_error); 130 - if (err == -ENODATA) { 131 - pr_debug("Failed to add events selected by BPF, debuginfo package not installed\n"); 132 - return TEST_SKIP; 133 - } 134 - if (err || list_empty(&parse_state.list)) { 135 - pr_debug("Failed to add events selected by BPF\n"); 136 - return TEST_FAIL; 137 - } 138 - 139 - snprintf(pid, sizeof(pid), "%d", getpid()); 140 - pid[sizeof(pid) - 1] = '\0'; 141 - opts.target.tid = opts.target.pid = pid; 142 - 143 - /* Instead of evlist__new_default, don't add default events */ 144 - evlist = evlist__new(); 145 - if (!evlist) { 146 - pr_debug("Not enough memory to create evlist\n"); 147 - return TEST_FAIL; 148 - } 149 - 150 - err = evlist__create_maps(evlist, &opts.target); 151 - if (err < 0) { 152 - pr_debug("Not enough memory to create thread/cpu maps\n"); 153 - goto out_delete_evlist; 154 - } 155 - 156 - evlist__splice_list_tail(evlist, &parse_state.list); 157 - 158 - evlist__config(evlist, &opts, NULL); 159 - 160 - err = evlist__open(evlist); 161 - if (err < 0) { 162 - pr_debug("perf_evlist__open: %s\n", 163 - str_error_r(errno, sbuf, sizeof(sbuf))); 164 - goto out_delete_evlist; 165 - } 166 - 167 - err = evlist__mmap(evlist, opts.mmap_pages); 168 - if (err < 0) { 169 - pr_debug("evlist__mmap: %s\n", 170 - str_error_r(errno, sbuf, sizeof(sbuf))); 171 - goto out_delete_evlist; 172 - } 173 - 174 - evlist__enable(evlist); 175 - (*func)(); 176 - evlist__disable(evlist); 177 - 178 - for (i = 0; i < evlist->core.nr_mmaps; i++) { 179 - union perf_event *event; 180 - struct mmap *md; 181 - 182 - md = &evlist->mmap[i]; 183 - if (perf_mmap__read_init(&md->core) < 0) 184 - continue; 185 - 186 - while ((event = perf_mmap__read_event(&md->core)) != NULL) { 187 - const u32 type = event->header.type; 188 - 189 - if (type == PERF_RECORD_SAMPLE) 190 - count ++; 191 - } 192 - perf_mmap__read_done(&md->core); 193 - } 194 - 195 - if (count != expect * evlist->core.nr_entries) { 196 - pr_debug("BPF filter result incorrect, expected %d, got %d samples\n", expect * evlist->core.nr_entries, count); 197 - goto out_delete_evlist; 198 - } 199 - 200 - ret = TEST_OK; 201 - 202 - out_delete_evlist: 203 - evlist__delete(evlist); 204 - return ret; 205 - } 206 - 207 - static struct bpf_object * 208 - prepare_bpf(void *obj_buf, size_t obj_buf_sz, const char *name) 209 - { 210 - struct bpf_object *obj; 211 - 212 - obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, name); 213 - if (IS_ERR(obj)) { 214 - pr_debug("Compile BPF program failed.\n"); 215 - return NULL; 216 - } 217 - return obj; 218 - } 219 - 220 - static int __test__bpf(int idx) 221 - { 222 - int ret; 223 - void *obj_buf; 224 - size_t obj_buf_sz; 225 - struct bpf_object *obj; 226 - 227 - ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, 228 - bpf_testcase_table[idx].prog_id, 229 - false, NULL); 230 - if (ret != TEST_OK || !obj_buf || !obj_buf_sz) { 231 - pr_debug("Unable to get BPF object, %s\n", 232 - bpf_testcase_table[idx].msg_compile_fail); 233 - if ((idx == 0) || (ret == TEST_SKIP)) 234 - return TEST_SKIP; 235 - else 236 - return TEST_FAIL; 237 - } 238 - 239 - obj = prepare_bpf(obj_buf, obj_buf_sz, 240 - bpf_testcase_table[idx].name); 241 - if ((!!bpf_testcase_table[idx].target_func) != (!!obj)) { 242 - if (!obj) 243 - pr_debug("Fail to load BPF object: %s\n", 244 - bpf_testcase_table[idx].msg_load_fail); 245 - else 246 - pr_debug("Success unexpectedly: %s\n", 247 - bpf_testcase_table[idx].msg_load_fail); 248 - ret = TEST_FAIL; 249 - goto out; 250 - } 251 - 252 - if (obj) { 253 - ret = do_test(obj, 254 - bpf_testcase_table[idx].target_func, 255 - bpf_testcase_table[idx].expect_result); 256 - if (ret != TEST_OK) 257 - goto out; 258 - if (bpf_testcase_table[idx].pin) { 259 - int err; 260 - 261 - if (!bpf_fs__mount()) { 262 - pr_debug("BPF filesystem not mounted\n"); 263 - ret = TEST_FAIL; 264 - goto out; 265 - } 266 - err = mkdir(PERF_TEST_BPF_PATH, 0777); 267 - if (err && errno != EEXIST) { 268 - pr_debug("Failed to make perf_test dir: %s\n", 269 - strerror(errno)); 270 - ret = TEST_FAIL; 271 - goto out; 272 - } 273 - if (bpf_object__pin(obj, PERF_TEST_BPF_PATH)) 274 - ret = TEST_FAIL; 275 - if (rm_rf(PERF_TEST_BPF_PATH)) 276 - ret = TEST_FAIL; 277 - } 278 - } 279 - 280 - out: 281 - free(obj_buf); 282 - bpf__clear(); 283 - return ret; 284 - } 285 - 286 - static int check_env(void) 287 - { 288 - LIBBPF_OPTS(bpf_prog_load_opts, opts); 289 - int err; 290 - char license[] = "GPL"; 291 - 292 - struct bpf_insn insns[] = { 293 - BPF_MOV64_IMM(BPF_REG_0, 1), 294 - BPF_EXIT_INSN(), 295 - }; 296 - 297 - err = fetch_kernel_version(&opts.kern_version, NULL, 0); 298 - if (err) { 299 - pr_debug("Unable to get kernel version\n"); 300 - return err; 301 - } 302 - err = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, license, insns, 303 - ARRAY_SIZE(insns), &opts); 304 - if (err < 0) { 305 - pr_err("Missing basic BPF support, skip this test: %s\n", 306 - strerror(errno)); 307 - return err; 308 - } 309 - close(err); 310 - 311 - return 0; 312 - } 313 - 314 - static int test__bpf(int i) 315 - { 316 - int err; 317 - 318 - if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table)) 319 - return TEST_FAIL; 320 - 321 - if (geteuid() != 0) { 322 - pr_debug("Only root can run BPF test\n"); 323 - return TEST_SKIP; 324 - } 325 - 326 - if (check_env()) 327 - return TEST_SKIP; 328 - 329 - err = __test__bpf(i); 330 - return err; 331 - } 332 - #endif 333 - 334 - static int test__basic_bpf_test(struct test_suite *test __maybe_unused, 335 - int subtest __maybe_unused) 336 - { 337 - #if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 338 - return test__bpf(0); 339 - #else 340 - pr_debug("Skip BPF test because BPF or libtraceevent support is not compiled\n"); 341 - return TEST_SKIP; 342 - #endif 343 - } 344 - 345 - static int test__bpf_pinning(struct test_suite *test __maybe_unused, 346 - int subtest __maybe_unused) 347 - { 348 - #if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 349 - return test__bpf(1); 350 - #else 351 - pr_debug("Skip BPF test because BPF or libtraceevent support is not compiled\n"); 352 - return TEST_SKIP; 353 - #endif 354 - } 355 - 356 - static int test__bpf_prologue_test(struct test_suite *test __maybe_unused, 357 - int subtest __maybe_unused) 358 - { 359 - #if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_BPF_PROLOGUE) && defined(HAVE_LIBTRACEEVENT) 360 - return test__bpf(2); 361 - #else 362 - pr_debug("Skip BPF test because BPF or libtraceevent support is not compiled\n"); 363 - return TEST_SKIP; 364 - #endif 365 - } 366 - 367 - 368 - static struct test_case bpf_tests[] = { 369 - #if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT) 370 - TEST_CASE("Basic BPF filtering", basic_bpf_test), 371 - TEST_CASE_REASON("BPF pinning", bpf_pinning, 372 - "clang isn't installed or environment missing BPF support"), 373 - #ifdef HAVE_BPF_PROLOGUE 374 - TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test, 375 - "clang/debuginfo isn't installed or environment missing BPF support"), 376 - #else 377 - TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test, "not compiled in"), 378 - #endif 379 - #else 380 - TEST_CASE_REASON("Basic BPF filtering", basic_bpf_test, "not compiled in or missing libtraceevent support"), 381 - TEST_CASE_REASON("BPF pinning", bpf_pinning, "not compiled in or missing libtraceevent support"), 382 - TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test, "not compiled in or missing libtraceevent support"), 383 - #endif 384 - { .name = NULL, } 385 - }; 386 - 387 - struct test_suite suite__bpf = { 388 - .desc = "BPF filter", 389 - .test_cases = bpf_tests, 390 - };
-2
tools/perf/tests/builtin-test.c
··· 92 92 &suite__fdarray__add, 93 93 &suite__kmod_path__parse, 94 94 &suite__thread_map, 95 - &suite__llvm, 96 95 &suite__session_topology, 97 - &suite__bpf, 98 96 &suite__thread_map_synthesize, 99 97 &suite__thread_map_remove, 100 98 &suite__cpu_map,
-219
tools/perf/tests/llvm.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - #include <stdio.h> 3 - #include <stdlib.h> 4 - #include <string.h> 5 - #include "tests.h" 6 - #include "debug.h" 7 - 8 - #ifdef HAVE_LIBBPF_SUPPORT 9 - #include <bpf/libbpf.h> 10 - #include <util/llvm-utils.h> 11 - #include "llvm.h" 12 - static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) 13 - { 14 - struct bpf_object *obj; 15 - 16 - obj = bpf_object__open_mem(obj_buf, obj_buf_sz, NULL); 17 - if (libbpf_get_error(obj)) 18 - return TEST_FAIL; 19 - bpf_object__close(obj); 20 - return TEST_OK; 21 - } 22 - 23 - static struct { 24 - const char *source; 25 - const char *desc; 26 - bool should_load_fail; 27 - } bpf_source_table[__LLVM_TESTCASE_MAX] = { 28 - [LLVM_TESTCASE_BASE] = { 29 - .source = test_llvm__bpf_base_prog, 30 - .desc = "Basic BPF llvm compile", 31 - }, 32 - [LLVM_TESTCASE_KBUILD] = { 33 - .source = test_llvm__bpf_test_kbuild_prog, 34 - .desc = "kbuild searching", 35 - }, 36 - [LLVM_TESTCASE_BPF_PROLOGUE] = { 37 - .source = test_llvm__bpf_test_prologue_prog, 38 - .desc = "Compile source for BPF prologue generation", 39 - }, 40 - [LLVM_TESTCASE_BPF_RELOCATION] = { 41 - .source = test_llvm__bpf_test_relocation, 42 - .desc = "Compile source for BPF relocation", 43 - .should_load_fail = true, 44 - }, 45 - }; 46 - 47 - int 48 - test_llvm__fetch_bpf_obj(void **p_obj_buf, 49 - size_t *p_obj_buf_sz, 50 - enum test_llvm__testcase idx, 51 - bool force, 52 - bool *should_load_fail) 53 - { 54 - const char *source; 55 - const char *desc; 56 - const char *tmpl_old, *clang_opt_old; 57 - char *tmpl_new = NULL, *clang_opt_new = NULL; 58 - int err, old_verbose, ret = TEST_FAIL; 59 - 60 - if (idx >= __LLVM_TESTCASE_MAX) 61 - return TEST_FAIL; 62 - 63 - source = bpf_source_table[idx].source; 64 - desc = bpf_source_table[idx].desc; 65 - if (should_load_fail) 66 - *should_load_fail = bpf_source_table[idx].should_load_fail; 67 - 68 - /* 69 - * Skip this test if user's .perfconfig doesn't set [llvm] section 70 - * and clang is not found in $PATH 71 - */ 72 - if (!force && (!llvm_param.user_set_param && 73 - llvm__search_clang())) { 74 - pr_debug("No clang, skip this test\n"); 75 - return TEST_SKIP; 76 - } 77 - 78 - /* 79 - * llvm is verbosity when error. Suppress all error output if 80 - * not 'perf test -v'. 81 - */ 82 - old_verbose = verbose; 83 - if (verbose == 0) 84 - verbose = -1; 85 - 86 - *p_obj_buf = NULL; 87 - *p_obj_buf_sz = 0; 88 - 89 - if (!llvm_param.clang_bpf_cmd_template) 90 - goto out; 91 - 92 - if (!llvm_param.clang_opt) 93 - llvm_param.clang_opt = strdup(""); 94 - 95 - err = asprintf(&tmpl_new, "echo '%s' | %s%s", source, 96 - llvm_param.clang_bpf_cmd_template, 97 - old_verbose ? "" : " 2>/dev/null"); 98 - if (err < 0) 99 - goto out; 100 - err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt); 101 - if (err < 0) 102 - goto out; 103 - 104 - tmpl_old = llvm_param.clang_bpf_cmd_template; 105 - llvm_param.clang_bpf_cmd_template = tmpl_new; 106 - clang_opt_old = llvm_param.clang_opt; 107 - llvm_param.clang_opt = clang_opt_new; 108 - 109 - err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz); 110 - 111 - llvm_param.clang_bpf_cmd_template = tmpl_old; 112 - llvm_param.clang_opt = clang_opt_old; 113 - 114 - verbose = old_verbose; 115 - if (err) 116 - goto out; 117 - 118 - ret = TEST_OK; 119 - out: 120 - free(tmpl_new); 121 - free(clang_opt_new); 122 - if (ret != TEST_OK) 123 - pr_debug("Failed to compile test case: '%s'\n", desc); 124 - return ret; 125 - } 126 - 127 - static int test__llvm(int subtest) 128 - { 129 - int ret; 130 - void *obj_buf = NULL; 131 - size_t obj_buf_sz = 0; 132 - bool should_load_fail = false; 133 - 134 - if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX)) 135 - return TEST_FAIL; 136 - 137 - ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, 138 - subtest, false, &should_load_fail); 139 - 140 - if (ret == TEST_OK && !should_load_fail) { 141 - ret = test__bpf_parsing(obj_buf, obj_buf_sz); 142 - if (ret != TEST_OK) { 143 - pr_debug("Failed to parse test case '%s'\n", 144 - bpf_source_table[subtest].desc); 145 - } 146 - } 147 - free(obj_buf); 148 - 149 - return ret; 150 - } 151 - #endif //HAVE_LIBBPF_SUPPORT 152 - 153 - static int test__llvm__bpf_base_prog(struct test_suite *test __maybe_unused, 154 - int subtest __maybe_unused) 155 - { 156 - #ifdef HAVE_LIBBPF_SUPPORT 157 - return test__llvm(LLVM_TESTCASE_BASE); 158 - #else 159 - pr_debug("Skip LLVM test because BPF support is not compiled\n"); 160 - return TEST_SKIP; 161 - #endif 162 - } 163 - 164 - static int test__llvm__bpf_test_kbuild_prog(struct test_suite *test __maybe_unused, 165 - int subtest __maybe_unused) 166 - { 167 - #ifdef HAVE_LIBBPF_SUPPORT 168 - return test__llvm(LLVM_TESTCASE_KBUILD); 169 - #else 170 - pr_debug("Skip LLVM test because BPF support is not compiled\n"); 171 - return TEST_SKIP; 172 - #endif 173 - } 174 - 175 - static int test__llvm__bpf_test_prologue_prog(struct test_suite *test __maybe_unused, 176 - int subtest __maybe_unused) 177 - { 178 - #ifdef HAVE_LIBBPF_SUPPORT 179 - return test__llvm(LLVM_TESTCASE_BPF_PROLOGUE); 180 - #else 181 - pr_debug("Skip LLVM test because BPF support is not compiled\n"); 182 - return TEST_SKIP; 183 - #endif 184 - } 185 - 186 - static int test__llvm__bpf_test_relocation(struct test_suite *test __maybe_unused, 187 - int subtest __maybe_unused) 188 - { 189 - #ifdef HAVE_LIBBPF_SUPPORT 190 - return test__llvm(LLVM_TESTCASE_BPF_RELOCATION); 191 - #else 192 - pr_debug("Skip LLVM test because BPF support is not compiled\n"); 193 - return TEST_SKIP; 194 - #endif 195 - } 196 - 197 - 198 - static struct test_case llvm_tests[] = { 199 - #ifdef HAVE_LIBBPF_SUPPORT 200 - TEST_CASE("Basic BPF llvm compile", llvm__bpf_base_prog), 201 - TEST_CASE("kbuild searching", llvm__bpf_test_kbuild_prog), 202 - TEST_CASE("Compile source for BPF prologue generation", 203 - llvm__bpf_test_prologue_prog), 204 - TEST_CASE("Compile source for BPF relocation", llvm__bpf_test_relocation), 205 - #else 206 - TEST_CASE_REASON("Basic BPF llvm compile", llvm__bpf_base_prog, "not compiled in"), 207 - TEST_CASE_REASON("kbuild searching", llvm__bpf_test_kbuild_prog, "not compiled in"), 208 - TEST_CASE_REASON("Compile source for BPF prologue generation", 209 - llvm__bpf_test_prologue_prog, "not compiled in"), 210 - TEST_CASE_REASON("Compile source for BPF relocation", 211 - llvm__bpf_test_relocation, "not compiled in"), 212 - #endif 213 - { .name = NULL, } 214 - }; 215 - 216 - struct test_suite suite__llvm = { 217 - .desc = "LLVM search and compile", 218 - .test_cases = llvm_tests, 219 - };
-31
tools/perf/tests/llvm.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef PERF_TEST_LLVM_H 3 - #define PERF_TEST_LLVM_H 4 - 5 - #ifdef __cplusplus 6 - extern "C" { 7 - #endif 8 - 9 - #include <stddef.h> /* for size_t */ 10 - #include <stdbool.h> /* for bool */ 11 - 12 - extern const char test_llvm__bpf_base_prog[]; 13 - extern const char test_llvm__bpf_test_kbuild_prog[]; 14 - extern const char test_llvm__bpf_test_prologue_prog[]; 15 - extern const char test_llvm__bpf_test_relocation[]; 16 - 17 - enum test_llvm__testcase { 18 - LLVM_TESTCASE_BASE, 19 - LLVM_TESTCASE_KBUILD, 20 - LLVM_TESTCASE_BPF_PROLOGUE, 21 - LLVM_TESTCASE_BPF_RELOCATION, 22 - __LLVM_TESTCASE_MAX, 23 - }; 24 - 25 - int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz, 26 - enum test_llvm__testcase index, bool force, 27 - bool *should_load_fail); 28 - #ifdef __cplusplus 29 - } 30 - #endif 31 - #endif
-2
tools/perf/tests/tests.h
··· 113 113 DECLARE_SUITE(fdarray__add); 114 114 DECLARE_SUITE(kmod_path__parse); 115 115 DECLARE_SUITE(thread_map); 116 - DECLARE_SUITE(llvm); 117 116 DECLARE_SUITE(bpf); 118 117 DECLARE_SUITE(session_topology); 119 118 DECLARE_SUITE(thread_map_synthesize); ··· 128 129 DECLARE_SUITE(is_printable_array); 129 130 DECLARE_SUITE(bitmap_print); 130 131 DECLARE_SUITE(perf_hooks); 131 - DECLARE_SUITE(clang); 132 132 DECLARE_SUITE(unit_number__scnprint); 133 133 DECLARE_SUITE(mem2node); 134 134 DECLARE_SUITE(maps__merge_in);
+1 -5
tools/perf/util/Build
··· 23 23 perf-y += find_bit.o 24 24 perf-y += get_current_dir_name.o 25 25 perf-y += levenshtein.o 26 - perf-y += llvm-utils.o 27 26 perf-y += mmap.o 28 27 perf-y += memswap.o 29 28 perf-y += parse-events.o ··· 149 150 perf-y += mutex.o 150 151 perf-y += sharded_mutex.o 151 152 152 - perf-$(CONFIG_LIBBPF) += bpf-loader.o 153 153 perf-$(CONFIG_LIBBPF) += bpf_map.o 154 154 perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter.o 155 155 perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter_cgroup.o ··· 166 168 perf-$(CONFIG_PERF_BPF_SKEL) += bpf_kwork.o 167 169 endif 168 170 169 - perf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o 170 171 perf-$(CONFIG_LIBELF) += symbol-elf.o 171 172 perf-$(CONFIG_LIBELF) += probe-file.o 172 173 perf-$(CONFIG_LIBELF) += probe-event.o ··· 232 235 perf-$(CONFIG_LIBPFM4) += pfm.o 233 236 234 237 CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" 235 - CFLAGS_llvm-utils.o += -DLIBBPF_INCLUDE_DIR="BUILD_STR($(libbpf_include_dir_SQ))" 236 238 237 239 # avoid compiler warnings in 32-bit mode 238 240 CFLAGS_genelf_debug.o += -Wno-packed ··· 323 327 bison_flags += -DYYNOMEM=YYABORT 324 328 endif 325 329 326 - CFLAGS_parse-events-flex.o += $(flex_flags) 330 + CFLAGS_parse-events-flex.o += $(flex_flags) -Wno-unused-label 327 331 CFLAGS_pmu-flex.o += $(flex_flags) 328 332 CFLAGS_expr-flex.o += $(flex_flags) 329 333 CFLAGS_bpf-filter-flex.o += $(flex_flags)
-1999
tools/perf/util/bpf-loader.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * bpf-loader.c 4 - * 5 - * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> 6 - * Copyright (C) 2015 Huawei Inc. 7 - */ 8 - 9 - #include <linux/bpf.h> 10 - #include <bpf/libbpf.h> 11 - #include <bpf/bpf.h> 12 - #include <linux/filter.h> 13 - #include <linux/err.h> 14 - #include <linux/kernel.h> 15 - #include <linux/string.h> 16 - #include <linux/zalloc.h> 17 - #include <errno.h> 18 - #include <stdlib.h> 19 - #include "debug.h" 20 - #include "evlist.h" 21 - #include "bpf-loader.h" 22 - #include "bpf-prologue.h" 23 - #include "probe-event.h" 24 - #include "probe-finder.h" // for MAX_PROBES 25 - #include "parse-events.h" 26 - #include "strfilter.h" 27 - #include "util.h" 28 - #include "llvm-utils.h" 29 - #include "util/hashmap.h" 30 - #include "asm/bug.h" 31 - 32 - #include <internal/xyarray.h> 33 - 34 - static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)), 35 - const char *fmt, va_list args) 36 - { 37 - return veprintf(1, verbose, pr_fmt(fmt), args); 38 - } 39 - 40 - struct bpf_prog_priv { 41 - bool is_tp; 42 - char *sys_name; 43 - char *evt_name; 44 - struct perf_probe_event pev; 45 - bool need_prologue; 46 - struct bpf_insn *insns_buf; 47 - int nr_types; 48 - int *type_mapping; 49 - int *prologue_fds; 50 - }; 51 - 52 - struct bpf_perf_object { 53 - struct list_head list; 54 - struct bpf_object *obj; 55 - }; 56 - 57 - struct bpf_preproc_result { 58 - struct bpf_insn *new_insn_ptr; 59 - int new_insn_cnt; 60 - }; 61 - 62 - static LIST_HEAD(bpf_objects_list); 63 - static struct hashmap *bpf_program_hash; 64 - static struct hashmap *bpf_map_hash; 65 - 66 - static struct bpf_perf_object * 67 - bpf_perf_object__next(struct bpf_perf_object *prev) 68 - { 69 - if (!prev) { 70 - if (list_empty(&bpf_objects_list)) 71 - return NULL; 72 - 73 - return list_first_entry(&bpf_objects_list, struct bpf_perf_object, list); 74 - } 75 - if (list_is_last(&prev->list, &bpf_objects_list)) 76 - return NULL; 77 - 78 - return list_next_entry(prev, list); 79 - } 80 - 81 - #define bpf_perf_object__for_each(perf_obj, tmp) \ 82 - for ((perf_obj) = bpf_perf_object__next(NULL), \ 83 - (tmp) = bpf_perf_object__next(perf_obj); \ 84 - (perf_obj) != NULL; \ 85 - (perf_obj) = (tmp), (tmp) = bpf_perf_object__next(tmp)) 86 - 87 - static bool libbpf_initialized; 88 - static int libbpf_sec_handler; 89 - 90 - static int bpf_perf_object__add(struct bpf_object *obj) 91 - { 92 - struct bpf_perf_object *perf_obj = zalloc(sizeof(*perf_obj)); 93 - 94 - if (perf_obj) { 95 - INIT_LIST_HEAD(&perf_obj->list); 96 - perf_obj->obj = obj; 97 - list_add_tail(&perf_obj->list, &bpf_objects_list); 98 - } 99 - return perf_obj ? 0 : -ENOMEM; 100 - } 101 - 102 - static void *program_priv(const struct bpf_program *prog) 103 - { 104 - void *priv; 105 - 106 - if (IS_ERR_OR_NULL(bpf_program_hash)) 107 - return NULL; 108 - if (!hashmap__find(bpf_program_hash, prog, &priv)) 109 - return NULL; 110 - return priv; 111 - } 112 - 113 - static struct bpf_insn prologue_init_insn[] = { 114 - BPF_MOV64_IMM(BPF_REG_2, 0), 115 - BPF_MOV64_IMM(BPF_REG_3, 0), 116 - BPF_MOV64_IMM(BPF_REG_4, 0), 117 - BPF_MOV64_IMM(BPF_REG_5, 0), 118 - }; 119 - 120 - static int libbpf_prog_prepare_load_fn(struct bpf_program *prog, 121 - struct bpf_prog_load_opts *opts __maybe_unused, 122 - long cookie __maybe_unused) 123 - { 124 - size_t init_size_cnt = ARRAY_SIZE(prologue_init_insn); 125 - size_t orig_insn_cnt, insn_cnt, init_size, orig_size; 126 - struct bpf_prog_priv *priv = program_priv(prog); 127 - const struct bpf_insn *orig_insn; 128 - struct bpf_insn *insn; 129 - 130 - if (IS_ERR_OR_NULL(priv)) { 131 - pr_debug("bpf: failed to get private field\n"); 132 - return -BPF_LOADER_ERRNO__INTERNAL; 133 - } 134 - 135 - if (!priv->need_prologue) 136 - return 0; 137 - 138 - /* prepend initialization code to program instructions */ 139 - orig_insn = bpf_program__insns(prog); 140 - orig_insn_cnt = bpf_program__insn_cnt(prog); 141 - init_size = init_size_cnt * sizeof(*insn); 142 - orig_size = orig_insn_cnt * sizeof(*insn); 143 - 144 - insn_cnt = orig_insn_cnt + init_size_cnt; 145 - insn = malloc(insn_cnt * sizeof(*insn)); 146 - if (!insn) 147 - return -ENOMEM; 148 - 149 - memcpy(insn, prologue_init_insn, init_size); 150 - memcpy((char *) insn + init_size, orig_insn, orig_size); 151 - bpf_program__set_insns(prog, insn, insn_cnt); 152 - return 0; 153 - } 154 - 155 - static int libbpf_init(void) 156 - { 157 - LIBBPF_OPTS(libbpf_prog_handler_opts, handler_opts, 158 - .prog_prepare_load_fn = libbpf_prog_prepare_load_fn, 159 - ); 160 - 161 - if (libbpf_initialized) 162 - return 0; 163 - 164 - libbpf_set_print(libbpf_perf_print); 165 - libbpf_sec_handler = libbpf_register_prog_handler(NULL, BPF_PROG_TYPE_KPROBE, 166 - 0, &handler_opts); 167 - if (libbpf_sec_handler < 0) { 168 - pr_debug("bpf: failed to register libbpf section handler: %d\n", 169 - libbpf_sec_handler); 170 - return -BPF_LOADER_ERRNO__INTERNAL; 171 - } 172 - libbpf_initialized = true; 173 - return 0; 174 - } 175 - 176 - struct bpf_object * 177 - bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name) 178 - { 179 - LIBBPF_OPTS(bpf_object_open_opts, opts, .object_name = name); 180 - struct bpf_object *obj; 181 - int err; 182 - 183 - err = libbpf_init(); 184 - if (err) 185 - return ERR_PTR(err); 186 - 187 - obj = bpf_object__open_mem(obj_buf, obj_buf_sz, &opts); 188 - if (IS_ERR_OR_NULL(obj)) { 189 - pr_debug("bpf: failed to load buffer\n"); 190 - return ERR_PTR(-EINVAL); 191 - } 192 - 193 - if (bpf_perf_object__add(obj)) { 194 - bpf_object__close(obj); 195 - return ERR_PTR(-ENOMEM); 196 - } 197 - 198 - return obj; 199 - } 200 - 201 - static void bpf_perf_object__close(struct bpf_perf_object *perf_obj) 202 - { 203 - list_del(&perf_obj->list); 204 - bpf_object__close(perf_obj->obj); 205 - free(perf_obj); 206 - } 207 - 208 - struct bpf_object *bpf__prepare_load(const char *filename, bool source) 209 - { 210 - LIBBPF_OPTS(bpf_object_open_opts, opts, .object_name = filename); 211 - struct bpf_object *obj; 212 - int err; 213 - 214 - err = libbpf_init(); 215 - if (err) 216 - return ERR_PTR(err); 217 - 218 - if (source) { 219 - void *obj_buf; 220 - size_t obj_buf_sz; 221 - 222 - err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz); 223 - if (err) 224 - return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); 225 - 226 - obj = bpf_object__open_mem(obj_buf, obj_buf_sz, &opts); 227 - 228 - if (!IS_ERR_OR_NULL(obj) && llvm_param.dump_obj) 229 - llvm__dump_obj(filename, obj_buf, obj_buf_sz); 230 - 231 - free(obj_buf); 232 - } else { 233 - obj = bpf_object__open(filename); 234 - } 235 - 236 - if (IS_ERR_OR_NULL(obj)) { 237 - pr_debug("bpf: failed to load %s\n", filename); 238 - return obj; 239 - } 240 - 241 - if (bpf_perf_object__add(obj)) { 242 - bpf_object__close(obj); 243 - return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); 244 - } 245 - 246 - return obj; 247 - } 248 - 249 - static void close_prologue_programs(struct bpf_prog_priv *priv) 250 - { 251 - struct perf_probe_event *pev; 252 - int i, fd; 253 - 254 - if (!priv->need_prologue) 255 - return; 256 - pev = &priv->pev; 257 - for (i = 0; i < pev->ntevs; i++) { 258 - fd = priv->prologue_fds[i]; 259 - if (fd != -1) 260 - close(fd); 261 - } 262 - } 263 - 264 - static void 265 - clear_prog_priv(const struct bpf_program *prog __maybe_unused, 266 - void *_priv) 267 - { 268 - struct bpf_prog_priv *priv = _priv; 269 - 270 - close_prologue_programs(priv); 271 - cleanup_perf_probe_events(&priv->pev, 1); 272 - zfree(&priv->insns_buf); 273 - zfree(&priv->prologue_fds); 274 - zfree(&priv->type_mapping); 275 - zfree(&priv->sys_name); 276 - zfree(&priv->evt_name); 277 - free(priv); 278 - } 279 - 280 - static void bpf_program_hash_free(void) 281 - { 282 - struct hashmap_entry *cur; 283 - size_t bkt; 284 - 285 - if (IS_ERR_OR_NULL(bpf_program_hash)) 286 - return; 287 - 288 - hashmap__for_each_entry(bpf_program_hash, cur, bkt) 289 - clear_prog_priv(cur->pkey, cur->pvalue); 290 - 291 - hashmap__free(bpf_program_hash); 292 - bpf_program_hash = NULL; 293 - } 294 - 295 - static void bpf_map_hash_free(void); 296 - 297 - void bpf__clear(void) 298 - { 299 - struct bpf_perf_object *perf_obj, *tmp; 300 - 301 - bpf_perf_object__for_each(perf_obj, tmp) { 302 - bpf__unprobe(perf_obj->obj); 303 - bpf_perf_object__close(perf_obj); 304 - } 305 - 306 - bpf_program_hash_free(); 307 - bpf_map_hash_free(); 308 - } 309 - 310 - static size_t ptr_hash(const long __key, void *ctx __maybe_unused) 311 - { 312 - return __key; 313 - } 314 - 315 - static bool ptr_equal(long key1, long key2, void *ctx __maybe_unused) 316 - { 317 - return key1 == key2; 318 - } 319 - 320 - static int program_set_priv(struct bpf_program *prog, void *priv) 321 - { 322 - void *old_priv; 323 - 324 - /* 325 - * Should not happen, we warn about it in the 326 - * caller function - config_bpf_program 327 - */ 328 - if (IS_ERR(bpf_program_hash)) 329 - return PTR_ERR(bpf_program_hash); 330 - 331 - if (!bpf_program_hash) { 332 - bpf_program_hash = hashmap__new(ptr_hash, ptr_equal, NULL); 333 - if (IS_ERR(bpf_program_hash)) 334 - return PTR_ERR(bpf_program_hash); 335 - } 336 - 337 - old_priv = program_priv(prog); 338 - if (old_priv) { 339 - clear_prog_priv(prog, old_priv); 340 - return hashmap__set(bpf_program_hash, prog, priv, NULL, NULL); 341 - } 342 - return hashmap__add(bpf_program_hash, prog, priv); 343 - } 344 - 345 - static int 346 - prog_config__exec(const char *value, struct perf_probe_event *pev) 347 - { 348 - pev->uprobes = true; 349 - pev->target = strdup(value); 350 - if (!pev->target) 351 - return -ENOMEM; 352 - return 0; 353 - } 354 - 355 - static int 356 - prog_config__module(const char *value, struct perf_probe_event *pev) 357 - { 358 - pev->uprobes = false; 359 - pev->target = strdup(value); 360 - if (!pev->target) 361 - return -ENOMEM; 362 - return 0; 363 - } 364 - 365 - static int 366 - prog_config__bool(const char *value, bool *pbool, bool invert) 367 - { 368 - int err; 369 - bool bool_value; 370 - 371 - if (!pbool) 372 - return -EINVAL; 373 - 374 - err = strtobool(value, &bool_value); 375 - if (err) 376 - return err; 377 - 378 - *pbool = invert ? !bool_value : bool_value; 379 - return 0; 380 - } 381 - 382 - static int 383 - prog_config__inlines(const char *value, 384 - struct perf_probe_event *pev __maybe_unused) 385 - { 386 - return prog_config__bool(value, &probe_conf.no_inlines, true); 387 - } 388 - 389 - static int 390 - prog_config__force(const char *value, 391 - struct perf_probe_event *pev __maybe_unused) 392 - { 393 - return prog_config__bool(value, &probe_conf.force_add, false); 394 - } 395 - 396 - static struct { 397 - const char *key; 398 - const char *usage; 399 - const char *desc; 400 - int (*func)(const char *, struct perf_probe_event *); 401 - } bpf_prog_config_terms[] = { 402 - { 403 - .key = "exec", 404 - .usage = "exec=<full path of file>", 405 - .desc = "Set uprobe target", 406 - .func = prog_config__exec, 407 - }, 408 - { 409 - .key = "module", 410 - .usage = "module=<module name> ", 411 - .desc = "Set kprobe module", 412 - .func = prog_config__module, 413 - }, 414 - { 415 - .key = "inlines", 416 - .usage = "inlines=[yes|no] ", 417 - .desc = "Probe at inline symbol", 418 - .func = prog_config__inlines, 419 - }, 420 - { 421 - .key = "force", 422 - .usage = "force=[yes|no] ", 423 - .desc = "Forcibly add events with existing name", 424 - .func = prog_config__force, 425 - }, 426 - }; 427 - 428 - static int 429 - do_prog_config(const char *key, const char *value, 430 - struct perf_probe_event *pev) 431 - { 432 - unsigned int i; 433 - 434 - pr_debug("config bpf program: %s=%s\n", key, value); 435 - for (i = 0; i < ARRAY_SIZE(bpf_prog_config_terms); i++) 436 - if (strcmp(key, bpf_prog_config_terms[i].key) == 0) 437 - return bpf_prog_config_terms[i].func(value, pev); 438 - 439 - pr_debug("BPF: ERROR: invalid program config option: %s=%s\n", 440 - key, value); 441 - 442 - pr_debug("\nHint: Valid options are:\n"); 443 - for (i = 0; i < ARRAY_SIZE(bpf_prog_config_terms); i++) 444 - pr_debug("\t%s:\t%s\n", bpf_prog_config_terms[i].usage, 445 - bpf_prog_config_terms[i].desc); 446 - pr_debug("\n"); 447 - 448 - return -BPF_LOADER_ERRNO__PROGCONF_TERM; 449 - } 450 - 451 - static const char * 452 - parse_prog_config_kvpair(const char *config_str, struct perf_probe_event *pev) 453 - { 454 - char *text = strdup(config_str); 455 - char *sep, *line; 456 - const char *main_str = NULL; 457 - int err = 0; 458 - 459 - if (!text) { 460 - pr_debug("Not enough memory: dup config_str failed\n"); 461 - return ERR_PTR(-ENOMEM); 462 - } 463 - 464 - line = text; 465 - while ((sep = strchr(line, ';'))) { 466 - char *equ; 467 - 468 - *sep = '\0'; 469 - equ = strchr(line, '='); 470 - if (!equ) { 471 - pr_warning("WARNING: invalid config in BPF object: %s\n", 472 - line); 473 - pr_warning("\tShould be 'key=value'.\n"); 474 - goto nextline; 475 - } 476 - *equ = '\0'; 477 - 478 - err = do_prog_config(line, equ + 1, pev); 479 - if (err) 480 - break; 481 - nextline: 482 - line = sep + 1; 483 - } 484 - 485 - if (!err) 486 - main_str = config_str + (line - text); 487 - free(text); 488 - 489 - return err ? ERR_PTR(err) : main_str; 490 - } 491 - 492 - static int 493 - parse_prog_config(const char *config_str, const char **p_main_str, 494 - bool *is_tp, struct perf_probe_event *pev) 495 - { 496 - int err; 497 - const char *main_str = parse_prog_config_kvpair(config_str, pev); 498 - 499 - if (IS_ERR(main_str)) 500 - return PTR_ERR(main_str); 501 - 502 - *p_main_str = main_str; 503 - if (!strchr(main_str, '=')) { 504 - /* Is a tracepoint event? */ 505 - const char *s = strchr(main_str, ':'); 506 - 507 - if (!s) { 508 - pr_debug("bpf: '%s' is not a valid tracepoint\n", 509 - config_str); 510 - return -BPF_LOADER_ERRNO__CONFIG; 511 - } 512 - 513 - *is_tp = true; 514 - return 0; 515 - } 516 - 517 - *is_tp = false; 518 - err = parse_perf_probe_command(main_str, pev); 519 - if (err < 0) { 520 - pr_debug("bpf: '%s' is not a valid config string\n", 521 - config_str); 522 - /* parse failed, don't need clear pev. */ 523 - return -BPF_LOADER_ERRNO__CONFIG; 524 - } 525 - return 0; 526 - } 527 - 528 - static int 529 - config_bpf_program(struct bpf_program *prog) 530 - { 531 - struct perf_probe_event *pev = NULL; 532 - struct bpf_prog_priv *priv = NULL; 533 - const char *config_str, *main_str; 534 - bool is_tp = false; 535 - int err; 536 - 537 - /* Initialize per-program probing setting */ 538 - probe_conf.no_inlines = false; 539 - probe_conf.force_add = false; 540 - 541 - priv = calloc(sizeof(*priv), 1); 542 - if (!priv) { 543 - pr_debug("bpf: failed to alloc priv\n"); 544 - return -ENOMEM; 545 - } 546 - pev = &priv->pev; 547 - 548 - config_str = bpf_program__section_name(prog); 549 - pr_debug("bpf: config program '%s'\n", config_str); 550 - err = parse_prog_config(config_str, &main_str, &is_tp, pev); 551 - if (err) 552 - goto errout; 553 - 554 - if (is_tp) { 555 - char *s = strchr(main_str, ':'); 556 - 557 - priv->is_tp = true; 558 - priv->sys_name = strndup(main_str, s - main_str); 559 - priv->evt_name = strdup(s + 1); 560 - goto set_priv; 561 - } 562 - 563 - if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) { 564 - pr_debug("bpf: '%s': group for event is set and not '%s'.\n", 565 - config_str, PERF_BPF_PROBE_GROUP); 566 - err = -BPF_LOADER_ERRNO__GROUP; 567 - goto errout; 568 - } else if (!pev->group) 569 - pev->group = strdup(PERF_BPF_PROBE_GROUP); 570 - 571 - if (!pev->group) { 572 - pr_debug("bpf: strdup failed\n"); 573 - err = -ENOMEM; 574 - goto errout; 575 - } 576 - 577 - if (!pev->event) { 578 - pr_debug("bpf: '%s': event name is missing. Section name should be 'key=value'\n", 579 - config_str); 580 - err = -BPF_LOADER_ERRNO__EVENTNAME; 581 - goto errout; 582 - } 583 - pr_debug("bpf: config '%s' is ok\n", config_str); 584 - 585 - set_priv: 586 - err = program_set_priv(prog, priv); 587 - if (err) { 588 - pr_debug("Failed to set priv for program '%s'\n", config_str); 589 - goto errout; 590 - } 591 - 592 - return 0; 593 - 594 - errout: 595 - if (pev) 596 - clear_perf_probe_event(pev); 597 - free(priv); 598 - return err; 599 - } 600 - 601 - static int bpf__prepare_probe(void) 602 - { 603 - static int err = 0; 604 - static bool initialized = false; 605 - 606 - /* 607 - * Make err static, so if init failed the first, bpf__prepare_probe() 608 - * fails each time without calling init_probe_symbol_maps multiple 609 - * times. 610 - */ 611 - if (initialized) 612 - return err; 613 - 614 - initialized = true; 615 - err = init_probe_symbol_maps(false); 616 - if (err < 0) 617 - pr_debug("Failed to init_probe_symbol_maps\n"); 618 - probe_conf.max_probes = MAX_PROBES; 619 - return err; 620 - } 621 - 622 - static int 623 - preproc_gen_prologue(struct bpf_program *prog, int n, 624 - const struct bpf_insn *orig_insns, int orig_insns_cnt, 625 - struct bpf_preproc_result *res) 626 - { 627 - struct bpf_prog_priv *priv = program_priv(prog); 628 - struct probe_trace_event *tev; 629 - struct perf_probe_event *pev; 630 - struct bpf_insn *buf; 631 - size_t prologue_cnt = 0; 632 - int i, err; 633 - 634 - if (IS_ERR_OR_NULL(priv) || priv->is_tp) 635 - goto errout; 636 - 637 - pev = &priv->pev; 638 - 639 - if (n < 0 || n >= priv->nr_types) 640 - goto errout; 641 - 642 - /* Find a tev belongs to that type */ 643 - for (i = 0; i < pev->ntevs; i++) { 644 - if (priv->type_mapping[i] == n) 645 - break; 646 - } 647 - 648 - if (i >= pev->ntevs) { 649 - pr_debug("Internal error: prologue type %d not found\n", n); 650 - return -BPF_LOADER_ERRNO__PROLOGUE; 651 - } 652 - 653 - tev = &pev->tevs[i]; 654 - 655 - buf = priv->insns_buf; 656 - err = bpf__gen_prologue(tev->args, tev->nargs, 657 - buf, &prologue_cnt, 658 - BPF_MAXINSNS - orig_insns_cnt); 659 - if (err) { 660 - const char *title; 661 - 662 - title = bpf_program__section_name(prog); 663 - pr_debug("Failed to generate prologue for program %s\n", 664 - title); 665 - return err; 666 - } 667 - 668 - memcpy(&buf[prologue_cnt], orig_insns, 669 - sizeof(struct bpf_insn) * orig_insns_cnt); 670 - 671 - res->new_insn_ptr = buf; 672 - res->new_insn_cnt = prologue_cnt + orig_insns_cnt; 673 - return 0; 674 - 675 - errout: 676 - pr_debug("Internal error in preproc_gen_prologue\n"); 677 - return -BPF_LOADER_ERRNO__PROLOGUE; 678 - } 679 - 680 - /* 681 - * compare_tev_args is reflexive, transitive and antisymmetric. 682 - * I can proof it but this margin is too narrow to contain. 683 - */ 684 - static int compare_tev_args(const void *ptev1, const void *ptev2) 685 - { 686 - int i, ret; 687 - const struct probe_trace_event *tev1 = 688 - *(const struct probe_trace_event **)ptev1; 689 - const struct probe_trace_event *tev2 = 690 - *(const struct probe_trace_event **)ptev2; 691 - 692 - ret = tev2->nargs - tev1->nargs; 693 - if (ret) 694 - return ret; 695 - 696 - for (i = 0; i < tev1->nargs; i++) { 697 - struct probe_trace_arg *arg1, *arg2; 698 - struct probe_trace_arg_ref *ref1, *ref2; 699 - 700 - arg1 = &tev1->args[i]; 701 - arg2 = &tev2->args[i]; 702 - 703 - ret = strcmp(arg1->value, arg2->value); 704 - if (ret) 705 - return ret; 706 - 707 - ref1 = arg1->ref; 708 - ref2 = arg2->ref; 709 - 710 - while (ref1 && ref2) { 711 - ret = ref2->offset - ref1->offset; 712 - if (ret) 713 - return ret; 714 - 715 - ref1 = ref1->next; 716 - ref2 = ref2->next; 717 - } 718 - 719 - if (ref1 || ref2) 720 - return ref2 ? 1 : -1; 721 - } 722 - 723 - return 0; 724 - } 725 - 726 - /* 727 - * Assign a type number to each tevs in a pev. 728 - * mapping is an array with same slots as tevs in that pev. 729 - * nr_types will be set to number of types. 730 - */ 731 - static int map_prologue(struct perf_probe_event *pev, int *mapping, 732 - int *nr_types) 733 - { 734 - int i, type = 0; 735 - struct probe_trace_event **ptevs; 736 - 737 - size_t array_sz = sizeof(*ptevs) * pev->ntevs; 738 - 739 - ptevs = malloc(array_sz); 740 - if (!ptevs) { 741 - pr_debug("Not enough memory: alloc ptevs failed\n"); 742 - return -ENOMEM; 743 - } 744 - 745 - pr_debug("In map_prologue, ntevs=%d\n", pev->ntevs); 746 - for (i = 0; i < pev->ntevs; i++) 747 - ptevs[i] = &pev->tevs[i]; 748 - 749 - qsort(ptevs, pev->ntevs, sizeof(*ptevs), 750 - compare_tev_args); 751 - 752 - for (i = 0; i < pev->ntevs; i++) { 753 - int n; 754 - 755 - n = ptevs[i] - pev->tevs; 756 - if (i == 0) { 757 - mapping[n] = type; 758 - pr_debug("mapping[%d]=%d\n", n, type); 759 - continue; 760 - } 761 - 762 - if (compare_tev_args(ptevs + i, ptevs + i - 1) == 0) 763 - mapping[n] = type; 764 - else 765 - mapping[n] = ++type; 766 - 767 - pr_debug("mapping[%d]=%d\n", n, mapping[n]); 768 - } 769 - free(ptevs); 770 - *nr_types = type + 1; 771 - 772 - return 0; 773 - } 774 - 775 - static int hook_load_preprocessor(struct bpf_program *prog) 776 - { 777 - struct bpf_prog_priv *priv = program_priv(prog); 778 - struct perf_probe_event *pev; 779 - bool need_prologue = false; 780 - int i; 781 - 782 - if (IS_ERR_OR_NULL(priv)) { 783 - pr_debug("Internal error when hook preprocessor\n"); 784 - return -BPF_LOADER_ERRNO__INTERNAL; 785 - } 786 - 787 - if (priv->is_tp) { 788 - priv->need_prologue = false; 789 - return 0; 790 - } 791 - 792 - pev = &priv->pev; 793 - for (i = 0; i < pev->ntevs; i++) { 794 - struct probe_trace_event *tev = &pev->tevs[i]; 795 - 796 - if (tev->nargs > 0) { 797 - need_prologue = true; 798 - break; 799 - } 800 - } 801 - 802 - /* 803 - * Since all tevs don't have argument, we don't need generate 804 - * prologue. 805 - */ 806 - if (!need_prologue) { 807 - priv->need_prologue = false; 808 - return 0; 809 - } 810 - 811 - priv->need_prologue = true; 812 - priv->insns_buf = malloc(sizeof(struct bpf_insn) * BPF_MAXINSNS); 813 - if (!priv->insns_buf) { 814 - pr_debug("Not enough memory: alloc insns_buf failed\n"); 815 - return -ENOMEM; 816 - } 817 - 818 - priv->prologue_fds = malloc(sizeof(int) * pev->ntevs); 819 - if (!priv->prologue_fds) { 820 - pr_debug("Not enough memory: alloc prologue fds failed\n"); 821 - return -ENOMEM; 822 - } 823 - memset(priv->prologue_fds, -1, sizeof(int) * pev->ntevs); 824 - 825 - priv->type_mapping = malloc(sizeof(int) * pev->ntevs); 826 - if (!priv->type_mapping) { 827 - pr_debug("Not enough memory: alloc type_mapping failed\n"); 828 - return -ENOMEM; 829 - } 830 - memset(priv->type_mapping, -1, 831 - sizeof(int) * pev->ntevs); 832 - 833 - return map_prologue(pev, priv->type_mapping, &priv->nr_types); 834 - } 835 - 836 - int bpf__probe(struct bpf_object *obj) 837 - { 838 - int err = 0; 839 - struct bpf_program *prog; 840 - struct bpf_prog_priv *priv; 841 - struct perf_probe_event *pev; 842 - 843 - err = bpf__prepare_probe(); 844 - if (err) { 845 - pr_debug("bpf__prepare_probe failed\n"); 846 - return err; 847 - } 848 - 849 - bpf_object__for_each_program(prog, obj) { 850 - err = config_bpf_program(prog); 851 - if (err) 852 - goto out; 853 - 854 - priv = program_priv(prog); 855 - if (IS_ERR_OR_NULL(priv)) { 856 - if (!priv) 857 - err = -BPF_LOADER_ERRNO__INTERNAL; 858 - else 859 - err = PTR_ERR(priv); 860 - goto out; 861 - } 862 - 863 - if (priv->is_tp) { 864 - bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT); 865 - continue; 866 - } 867 - 868 - bpf_program__set_type(prog, BPF_PROG_TYPE_KPROBE); 869 - pev = &priv->pev; 870 - 871 - err = convert_perf_probe_events(pev, 1); 872 - if (err < 0) { 873 - pr_debug("bpf_probe: failed to convert perf probe events\n"); 874 - goto out; 875 - } 876 - 877 - err = apply_perf_probe_events(pev, 1); 878 - if (err < 0) { 879 - pr_debug("bpf_probe: failed to apply perf probe events\n"); 880 - goto out; 881 - } 882 - 883 - /* 884 - * After probing, let's consider prologue, which 885 - * adds program fetcher to BPF programs. 886 - * 887 - * hook_load_preprocessor() hooks pre-processor 888 - * to bpf_program, let it generate prologue 889 - * dynamically during loading. 890 - */ 891 - err = hook_load_preprocessor(prog); 892 - if (err) 893 - goto out; 894 - } 895 - out: 896 - return err < 0 ? err : 0; 897 - } 898 - 899 - #define EVENTS_WRITE_BUFSIZE 4096 900 - int bpf__unprobe(struct bpf_object *obj) 901 - { 902 - int err, ret = 0; 903 - struct bpf_program *prog; 904 - 905 - bpf_object__for_each_program(prog, obj) { 906 - struct bpf_prog_priv *priv = program_priv(prog); 907 - int i; 908 - 909 - if (IS_ERR_OR_NULL(priv) || priv->is_tp) 910 - continue; 911 - 912 - for (i = 0; i < priv->pev.ntevs; i++) { 913 - struct probe_trace_event *tev = &priv->pev.tevs[i]; 914 - char name_buf[EVENTS_WRITE_BUFSIZE]; 915 - struct strfilter *delfilter; 916 - 917 - snprintf(name_buf, EVENTS_WRITE_BUFSIZE, 918 - "%s:%s", tev->group, tev->event); 919 - name_buf[EVENTS_WRITE_BUFSIZE - 1] = '\0'; 920 - 921 - delfilter = strfilter__new(name_buf, NULL); 922 - if (!delfilter) { 923 - pr_debug("Failed to create filter for unprobing\n"); 924 - ret = -ENOMEM; 925 - continue; 926 - } 927 - 928 - err = del_perf_probe_events(delfilter); 929 - strfilter__delete(delfilter); 930 - if (err) { 931 - pr_debug("Failed to delete %s\n", name_buf); 932 - ret = err; 933 - continue; 934 - } 935 - } 936 - } 937 - return ret; 938 - } 939 - 940 - static int bpf_object__load_prologue(struct bpf_object *obj) 941 - { 942 - int init_cnt = ARRAY_SIZE(prologue_init_insn); 943 - const struct bpf_insn *orig_insns; 944 - struct bpf_preproc_result res; 945 - struct perf_probe_event *pev; 946 - struct bpf_program *prog; 947 - int orig_insns_cnt; 948 - 949 - bpf_object__for_each_program(prog, obj) { 950 - struct bpf_prog_priv *priv = program_priv(prog); 951 - int err, i, fd; 952 - 953 - if (IS_ERR_OR_NULL(priv)) { 954 - pr_debug("bpf: failed to get private field\n"); 955 - return -BPF_LOADER_ERRNO__INTERNAL; 956 - } 957 - 958 - if (!priv->need_prologue) 959 - continue; 960 - 961 - /* 962 - * For each program that needs prologue we do following: 963 - * 964 - * - take its current instructions and use them 965 - * to generate the new code with prologue 966 - * - load new instructions with bpf_prog_load 967 - * and keep the fd in prologue_fds 968 - * - new fd will be used in bpf__foreach_event 969 - * to connect this program with perf evsel 970 - */ 971 - orig_insns = bpf_program__insns(prog); 972 - orig_insns_cnt = bpf_program__insn_cnt(prog); 973 - 974 - pev = &priv->pev; 975 - for (i = 0; i < pev->ntevs; i++) { 976 - /* 977 - * Skipping artificall prologue_init_insn instructions 978 - * (init_cnt), so the prologue can be generated instead 979 - * of them. 980 - */ 981 - err = preproc_gen_prologue(prog, i, 982 - orig_insns + init_cnt, 983 - orig_insns_cnt - init_cnt, 984 - &res); 985 - if (err) 986 - return err; 987 - 988 - fd = bpf_prog_load(bpf_program__get_type(prog), 989 - bpf_program__name(prog), "GPL", 990 - res.new_insn_ptr, 991 - res.new_insn_cnt, NULL); 992 - if (fd < 0) { 993 - char bf[128]; 994 - 995 - libbpf_strerror(-errno, bf, sizeof(bf)); 996 - pr_debug("bpf: load objects with prologue failed: err=%d: (%s)\n", 997 - -errno, bf); 998 - return -errno; 999 - } 1000 - priv->prologue_fds[i] = fd; 1001 - } 1002 - /* 1003 - * We no longer need the original program, 1004 - * we can unload it. 1005 - */ 1006 - bpf_program__unload(prog); 1007 - } 1008 - return 0; 1009 - } 1010 - 1011 - int bpf__load(struct bpf_object *obj) 1012 - { 1013 - int err; 1014 - 1015 - err = bpf_object__load(obj); 1016 - if (err) { 1017 - char bf[128]; 1018 - libbpf_strerror(err, bf, sizeof(bf)); 1019 - pr_debug("bpf: load objects failed: err=%d: (%s)\n", err, bf); 1020 - return err; 1021 - } 1022 - return bpf_object__load_prologue(obj); 1023 - } 1024 - 1025 - int bpf__foreach_event(struct bpf_object *obj, 1026 - bpf_prog_iter_callback_t func, 1027 - void *arg) 1028 - { 1029 - struct bpf_program *prog; 1030 - int err; 1031 - 1032 - bpf_object__for_each_program(prog, obj) { 1033 - struct bpf_prog_priv *priv = program_priv(prog); 1034 - struct probe_trace_event *tev; 1035 - struct perf_probe_event *pev; 1036 - int i, fd; 1037 - 1038 - if (IS_ERR_OR_NULL(priv)) { 1039 - pr_debug("bpf: failed to get private field\n"); 1040 - return -BPF_LOADER_ERRNO__INTERNAL; 1041 - } 1042 - 1043 - if (priv->is_tp) { 1044 - fd = bpf_program__fd(prog); 1045 - err = (*func)(priv->sys_name, priv->evt_name, fd, obj, arg); 1046 - if (err) { 1047 - pr_debug("bpf: tracepoint call back failed, stop iterate\n"); 1048 - return err; 1049 - } 1050 - continue; 1051 - } 1052 - 1053 - pev = &priv->pev; 1054 - for (i = 0; i < pev->ntevs; i++) { 1055 - tev = &pev->tevs[i]; 1056 - 1057 - if (priv->need_prologue) 1058 - fd = priv->prologue_fds[i]; 1059 - else 1060 - fd = bpf_program__fd(prog); 1061 - 1062 - if (fd < 0) { 1063 - pr_debug("bpf: failed to get file descriptor\n"); 1064 - return fd; 1065 - } 1066 - 1067 - err = (*func)(tev->group, tev->event, fd, obj, arg); 1068 - if (err) { 1069 - pr_debug("bpf: call back failed, stop iterate\n"); 1070 - return err; 1071 - } 1072 - } 1073 - } 1074 - return 0; 1075 - } 1076 - 1077 - enum bpf_map_op_type { 1078 - BPF_MAP_OP_SET_VALUE, 1079 - BPF_MAP_OP_SET_EVSEL, 1080 - }; 1081 - 1082 - enum bpf_map_key_type { 1083 - BPF_MAP_KEY_ALL, 1084 - }; 1085 - 1086 - struct bpf_map_op { 1087 - struct list_head list; 1088 - enum bpf_map_op_type op_type; 1089 - enum bpf_map_key_type key_type; 1090 - union { 1091 - u64 value; 1092 - struct evsel *evsel; 1093 - } v; 1094 - }; 1095 - 1096 - struct bpf_map_priv { 1097 - struct list_head ops_list; 1098 - }; 1099 - 1100 - static void 1101 - bpf_map_op__delete(struct bpf_map_op *op) 1102 - { 1103 - if (!list_empty(&op->list)) 1104 - list_del_init(&op->list); 1105 - free(op); 1106 - } 1107 - 1108 - static void 1109 - bpf_map_priv__purge(struct bpf_map_priv *priv) 1110 - { 1111 - struct bpf_map_op *pos, *n; 1112 - 1113 - list_for_each_entry_safe(pos, n, &priv->ops_list, list) { 1114 - list_del_init(&pos->list); 1115 - bpf_map_op__delete(pos); 1116 - } 1117 - } 1118 - 1119 - static void 1120 - bpf_map_priv__clear(const struct bpf_map *map __maybe_unused, 1121 - void *_priv) 1122 - { 1123 - struct bpf_map_priv *priv = _priv; 1124 - 1125 - bpf_map_priv__purge(priv); 1126 - free(priv); 1127 - } 1128 - 1129 - static void *map_priv(const struct bpf_map *map) 1130 - { 1131 - void *priv; 1132 - 1133 - if (IS_ERR_OR_NULL(bpf_map_hash)) 1134 - return NULL; 1135 - if (!hashmap__find(bpf_map_hash, map, &priv)) 1136 - return NULL; 1137 - return priv; 1138 - } 1139 - 1140 - static void bpf_map_hash_free(void) 1141 - { 1142 - struct hashmap_entry *cur; 1143 - size_t bkt; 1144 - 1145 - if (IS_ERR_OR_NULL(bpf_map_hash)) 1146 - return; 1147 - 1148 - hashmap__for_each_entry(bpf_map_hash, cur, bkt) 1149 - bpf_map_priv__clear(cur->pkey, cur->pvalue); 1150 - 1151 - hashmap__free(bpf_map_hash); 1152 - bpf_map_hash = NULL; 1153 - } 1154 - 1155 - static int map_set_priv(struct bpf_map *map, void *priv) 1156 - { 1157 - void *old_priv; 1158 - 1159 - if (WARN_ON_ONCE(IS_ERR(bpf_map_hash))) 1160 - return PTR_ERR(bpf_program_hash); 1161 - 1162 - if (!bpf_map_hash) { 1163 - bpf_map_hash = hashmap__new(ptr_hash, ptr_equal, NULL); 1164 - if (IS_ERR(bpf_map_hash)) 1165 - return PTR_ERR(bpf_map_hash); 1166 - } 1167 - 1168 - old_priv = map_priv(map); 1169 - if (old_priv) { 1170 - bpf_map_priv__clear(map, old_priv); 1171 - return hashmap__set(bpf_map_hash, map, priv, NULL, NULL); 1172 - } 1173 - return hashmap__add(bpf_map_hash, map, priv); 1174 - } 1175 - 1176 - static int 1177 - bpf_map_op_setkey(struct bpf_map_op *op, struct parse_events_term *term) 1178 - { 1179 - op->key_type = BPF_MAP_KEY_ALL; 1180 - if (!term) 1181 - return 0; 1182 - 1183 - return 0; 1184 - } 1185 - 1186 - static struct bpf_map_op * 1187 - bpf_map_op__new(struct parse_events_term *term) 1188 - { 1189 - struct bpf_map_op *op; 1190 - int err; 1191 - 1192 - op = zalloc(sizeof(*op)); 1193 - if (!op) { 1194 - pr_debug("Failed to alloc bpf_map_op\n"); 1195 - return ERR_PTR(-ENOMEM); 1196 - } 1197 - INIT_LIST_HEAD(&op->list); 1198 - 1199 - err = bpf_map_op_setkey(op, term); 1200 - if (err) { 1201 - free(op); 1202 - return ERR_PTR(err); 1203 - } 1204 - return op; 1205 - } 1206 - 1207 - static struct bpf_map_op * 1208 - bpf_map_op__clone(struct bpf_map_op *op) 1209 - { 1210 - struct bpf_map_op *newop; 1211 - 1212 - newop = memdup(op, sizeof(*op)); 1213 - if (!newop) { 1214 - pr_debug("Failed to alloc bpf_map_op\n"); 1215 - return NULL; 1216 - } 1217 - 1218 - INIT_LIST_HEAD(&newop->list); 1219 - return newop; 1220 - } 1221 - 1222 - static struct bpf_map_priv * 1223 - bpf_map_priv__clone(struct bpf_map_priv *priv) 1224 - { 1225 - struct bpf_map_priv *newpriv; 1226 - struct bpf_map_op *pos, *newop; 1227 - 1228 - newpriv = zalloc(sizeof(*newpriv)); 1229 - if (!newpriv) { 1230 - pr_debug("Not enough memory to alloc map private\n"); 1231 - return NULL; 1232 - } 1233 - INIT_LIST_HEAD(&newpriv->ops_list); 1234 - 1235 - list_for_each_entry(pos, &priv->ops_list, list) { 1236 - newop = bpf_map_op__clone(pos); 1237 - if (!newop) { 1238 - bpf_map_priv__purge(newpriv); 1239 - return NULL; 1240 - } 1241 - list_add_tail(&newop->list, &newpriv->ops_list); 1242 - } 1243 - 1244 - return newpriv; 1245 - } 1246 - 1247 - static int 1248 - bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op) 1249 - { 1250 - const char *map_name = bpf_map__name(map); 1251 - struct bpf_map_priv *priv = map_priv(map); 1252 - 1253 - if (IS_ERR(priv)) { 1254 - pr_debug("Failed to get private from map %s\n", map_name); 1255 - return PTR_ERR(priv); 1256 - } 1257 - 1258 - if (!priv) { 1259 - priv = zalloc(sizeof(*priv)); 1260 - if (!priv) { 1261 - pr_debug("Not enough memory to alloc map private\n"); 1262 - return -ENOMEM; 1263 - } 1264 - INIT_LIST_HEAD(&priv->ops_list); 1265 - 1266 - if (map_set_priv(map, priv)) { 1267 - free(priv); 1268 - return -BPF_LOADER_ERRNO__INTERNAL; 1269 - } 1270 - } 1271 - 1272 - list_add_tail(&op->list, &priv->ops_list); 1273 - return 0; 1274 - } 1275 - 1276 - static struct bpf_map_op * 1277 - bpf_map__add_newop(struct bpf_map *map, struct parse_events_term *term) 1278 - { 1279 - struct bpf_map_op *op; 1280 - int err; 1281 - 1282 - op = bpf_map_op__new(term); 1283 - if (IS_ERR(op)) 1284 - return op; 1285 - 1286 - err = bpf_map__add_op(map, op); 1287 - if (err) { 1288 - bpf_map_op__delete(op); 1289 - return ERR_PTR(err); 1290 - } 1291 - return op; 1292 - } 1293 - 1294 - static int 1295 - __bpf_map__config_value(struct bpf_map *map, 1296 - struct parse_events_term *term) 1297 - { 1298 - struct bpf_map_op *op; 1299 - const char *map_name = bpf_map__name(map); 1300 - 1301 - if (!map) { 1302 - pr_debug("Map '%s' is invalid\n", map_name); 1303 - return -BPF_LOADER_ERRNO__INTERNAL; 1304 - } 1305 - 1306 - if (bpf_map__type(map) != BPF_MAP_TYPE_ARRAY) { 1307 - pr_debug("Map %s type is not BPF_MAP_TYPE_ARRAY\n", 1308 - map_name); 1309 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE; 1310 - } 1311 - if (bpf_map__key_size(map) < sizeof(unsigned int)) { 1312 - pr_debug("Map %s has incorrect key size\n", map_name); 1313 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE; 1314 - } 1315 - switch (bpf_map__value_size(map)) { 1316 - case 1: 1317 - case 2: 1318 - case 4: 1319 - case 8: 1320 - break; 1321 - default: 1322 - pr_debug("Map %s has incorrect value size\n", map_name); 1323 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE; 1324 - } 1325 - 1326 - op = bpf_map__add_newop(map, term); 1327 - if (IS_ERR(op)) 1328 - return PTR_ERR(op); 1329 - op->op_type = BPF_MAP_OP_SET_VALUE; 1330 - op->v.value = term->val.num; 1331 - return 0; 1332 - } 1333 - 1334 - static int 1335 - bpf_map__config_value(struct bpf_map *map, 1336 - struct parse_events_term *term, 1337 - struct evlist *evlist __maybe_unused) 1338 - { 1339 - if (!term->err_val) { 1340 - pr_debug("Config value not set\n"); 1341 - return -BPF_LOADER_ERRNO__OBJCONF_CONF; 1342 - } 1343 - 1344 - if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM) { 1345 - pr_debug("ERROR: wrong value type for 'value'\n"); 1346 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE; 1347 - } 1348 - 1349 - return __bpf_map__config_value(map, term); 1350 - } 1351 - 1352 - static int 1353 - __bpf_map__config_event(struct bpf_map *map, 1354 - struct parse_events_term *term, 1355 - struct evlist *evlist) 1356 - { 1357 - struct bpf_map_op *op; 1358 - const char *map_name = bpf_map__name(map); 1359 - struct evsel *evsel = evlist__find_evsel_by_str(evlist, term->val.str); 1360 - 1361 - if (!evsel) { 1362 - pr_debug("Event (for '%s') '%s' doesn't exist\n", 1363 - map_name, term->val.str); 1364 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_NOEVT; 1365 - } 1366 - 1367 - if (!map) { 1368 - pr_debug("Map '%s' is invalid\n", map_name); 1369 - return PTR_ERR(map); 1370 - } 1371 - 1372 - /* 1373 - * No need to check key_size and value_size: 1374 - * kernel has already checked them. 1375 - */ 1376 - if (bpf_map__type(map) != BPF_MAP_TYPE_PERF_EVENT_ARRAY) { 1377 - pr_debug("Map %s type is not BPF_MAP_TYPE_PERF_EVENT_ARRAY\n", 1378 - map_name); 1379 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE; 1380 - } 1381 - 1382 - op = bpf_map__add_newop(map, term); 1383 - if (IS_ERR(op)) 1384 - return PTR_ERR(op); 1385 - op->op_type = BPF_MAP_OP_SET_EVSEL; 1386 - op->v.evsel = evsel; 1387 - return 0; 1388 - } 1389 - 1390 - static int 1391 - bpf_map__config_event(struct bpf_map *map, 1392 - struct parse_events_term *term, 1393 - struct evlist *evlist) 1394 - { 1395 - if (!term->err_val) { 1396 - pr_debug("Config value not set\n"); 1397 - return -BPF_LOADER_ERRNO__OBJCONF_CONF; 1398 - } 1399 - 1400 - if (term->type_val != PARSE_EVENTS__TERM_TYPE_STR) { 1401 - pr_debug("ERROR: wrong value type for 'event'\n"); 1402 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE; 1403 - } 1404 - 1405 - return __bpf_map__config_event(map, term, evlist); 1406 - } 1407 - 1408 - struct bpf_obj_config__map_func { 1409 - const char *config_opt; 1410 - int (*config_func)(struct bpf_map *, struct parse_events_term *, 1411 - struct evlist *); 1412 - }; 1413 - 1414 - struct bpf_obj_config__map_func bpf_obj_config__map_funcs[] = { 1415 - {"value", bpf_map__config_value}, 1416 - {"event", bpf_map__config_event}, 1417 - }; 1418 - 1419 - static int 1420 - bpf__obj_config_map(struct bpf_object *obj, 1421 - struct parse_events_term *term, 1422 - struct evlist *evlist, 1423 - int *key_scan_pos) 1424 - { 1425 - /* key is "map:<mapname>.<config opt>" */ 1426 - char *map_name = strdup(term->config + sizeof("map:") - 1); 1427 - struct bpf_map *map; 1428 - int err = -BPF_LOADER_ERRNO__OBJCONF_OPT; 1429 - char *map_opt; 1430 - size_t i; 1431 - 1432 - if (!map_name) 1433 - return -ENOMEM; 1434 - 1435 - map_opt = strchr(map_name, '.'); 1436 - if (!map_opt) { 1437 - pr_debug("ERROR: Invalid map config: %s\n", map_name); 1438 - goto out; 1439 - } 1440 - 1441 - *map_opt++ = '\0'; 1442 - if (*map_opt == '\0') { 1443 - pr_debug("ERROR: Invalid map option: %s\n", term->config); 1444 - goto out; 1445 - } 1446 - 1447 - map = bpf_object__find_map_by_name(obj, map_name); 1448 - if (!map) { 1449 - pr_debug("ERROR: Map %s doesn't exist\n", map_name); 1450 - err = -BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST; 1451 - goto out; 1452 - } 1453 - 1454 - for (i = 0; i < ARRAY_SIZE(bpf_obj_config__map_funcs); i++) { 1455 - struct bpf_obj_config__map_func *func = 1456 - &bpf_obj_config__map_funcs[i]; 1457 - 1458 - if (strcmp(map_opt, func->config_opt) == 0) { 1459 - err = func->config_func(map, term, evlist); 1460 - goto out; 1461 - } 1462 - } 1463 - 1464 - pr_debug("ERROR: Invalid map config option '%s'\n", map_opt); 1465 - err = -BPF_LOADER_ERRNO__OBJCONF_MAP_OPT; 1466 - out: 1467 - if (!err) 1468 - *key_scan_pos += strlen(map_opt); 1469 - 1470 - free(map_name); 1471 - return err; 1472 - } 1473 - 1474 - int bpf__config_obj(struct bpf_object *obj, 1475 - struct parse_events_term *term, 1476 - struct evlist *evlist, 1477 - int *error_pos) 1478 - { 1479 - int key_scan_pos = 0; 1480 - int err; 1481 - 1482 - if (!obj || !term || !term->config) 1483 - return -EINVAL; 1484 - 1485 - if (strstarts(term->config, "map:")) { 1486 - key_scan_pos = sizeof("map:") - 1; 1487 - err = bpf__obj_config_map(obj, term, evlist, &key_scan_pos); 1488 - goto out; 1489 - } 1490 - err = -BPF_LOADER_ERRNO__OBJCONF_OPT; 1491 - out: 1492 - if (error_pos) 1493 - *error_pos = key_scan_pos; 1494 - return err; 1495 - 1496 - } 1497 - 1498 - typedef int (*map_config_func_t)(const char *name, int map_fd, 1499 - const struct bpf_map *map, 1500 - struct bpf_map_op *op, 1501 - void *pkey, void *arg); 1502 - static int 1503 - foreach_key_array_all(map_config_func_t func, 1504 - void *arg, const char *name, 1505 - int map_fd, const struct bpf_map *map, 1506 - struct bpf_map_op *op) 1507 - { 1508 - unsigned int i; 1509 - int err; 1510 - 1511 - for (i = 0; i < bpf_map__max_entries(map); i++) { 1512 - err = func(name, map_fd, map, op, &i, arg); 1513 - if (err) { 1514 - pr_debug("ERROR: failed to insert value to %s[%u]\n", 1515 - name, i); 1516 - return err; 1517 - } 1518 - } 1519 - return 0; 1520 - } 1521 - 1522 - 1523 - static int 1524 - bpf_map_config_foreach_key(struct bpf_map *map, 1525 - map_config_func_t func, 1526 - void *arg) 1527 - { 1528 - int err, map_fd, type; 1529 - struct bpf_map_op *op; 1530 - const char *name = bpf_map__name(map); 1531 - struct bpf_map_priv *priv = map_priv(map); 1532 - 1533 - if (IS_ERR(priv)) { 1534 - pr_debug("ERROR: failed to get private from map %s\n", name); 1535 - return -BPF_LOADER_ERRNO__INTERNAL; 1536 - } 1537 - if (!priv || list_empty(&priv->ops_list)) { 1538 - pr_debug("INFO: nothing to config for map %s\n", name); 1539 - return 0; 1540 - } 1541 - 1542 - if (!map) { 1543 - pr_debug("Map '%s' is invalid\n", name); 1544 - return -BPF_LOADER_ERRNO__INTERNAL; 1545 - } 1546 - map_fd = bpf_map__fd(map); 1547 - if (map_fd < 0) { 1548 - pr_debug("ERROR: failed to get fd from map %s\n", name); 1549 - return map_fd; 1550 - } 1551 - 1552 - type = bpf_map__type(map); 1553 - list_for_each_entry(op, &priv->ops_list, list) { 1554 - switch (type) { 1555 - case BPF_MAP_TYPE_ARRAY: 1556 - case BPF_MAP_TYPE_PERF_EVENT_ARRAY: 1557 - switch (op->key_type) { 1558 - case BPF_MAP_KEY_ALL: 1559 - err = foreach_key_array_all(func, arg, name, 1560 - map_fd, map, op); 1561 - break; 1562 - default: 1563 - pr_debug("ERROR: keytype for map '%s' invalid\n", 1564 - name); 1565 - return -BPF_LOADER_ERRNO__INTERNAL; 1566 - } 1567 - if (err) 1568 - return err; 1569 - break; 1570 - default: 1571 - pr_debug("ERROR: type of '%s' incorrect\n", name); 1572 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE; 1573 - } 1574 - } 1575 - 1576 - return 0; 1577 - } 1578 - 1579 - static int 1580 - apply_config_value_for_key(int map_fd, void *pkey, 1581 - size_t val_size, u64 val) 1582 - { 1583 - int err = 0; 1584 - 1585 - switch (val_size) { 1586 - case 1: { 1587 - u8 _val = (u8)(val); 1588 - err = bpf_map_update_elem(map_fd, pkey, &_val, BPF_ANY); 1589 - break; 1590 - } 1591 - case 2: { 1592 - u16 _val = (u16)(val); 1593 - err = bpf_map_update_elem(map_fd, pkey, &_val, BPF_ANY); 1594 - break; 1595 - } 1596 - case 4: { 1597 - u32 _val = (u32)(val); 1598 - err = bpf_map_update_elem(map_fd, pkey, &_val, BPF_ANY); 1599 - break; 1600 - } 1601 - case 8: { 1602 - err = bpf_map_update_elem(map_fd, pkey, &val, BPF_ANY); 1603 - break; 1604 - } 1605 - default: 1606 - pr_debug("ERROR: invalid value size\n"); 1607 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE; 1608 - } 1609 - if (err && errno) 1610 - err = -errno; 1611 - return err; 1612 - } 1613 - 1614 - static int 1615 - apply_config_evsel_for_key(const char *name, int map_fd, void *pkey, 1616 - struct evsel *evsel) 1617 - { 1618 - struct xyarray *xy = evsel->core.fd; 1619 - struct perf_event_attr *attr; 1620 - unsigned int key, events; 1621 - bool check_pass = false; 1622 - int *evt_fd; 1623 - int err; 1624 - 1625 - if (!xy) { 1626 - pr_debug("ERROR: evsel not ready for map %s\n", name); 1627 - return -BPF_LOADER_ERRNO__INTERNAL; 1628 - } 1629 - 1630 - if (xy->row_size / xy->entry_size != 1) { 1631 - pr_debug("ERROR: Dimension of target event is incorrect for map %s\n", 1632 - name); 1633 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM; 1634 - } 1635 - 1636 - attr = &evsel->core.attr; 1637 - if (attr->inherit) { 1638 - pr_debug("ERROR: Can't put inherit event into map %s\n", name); 1639 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH; 1640 - } 1641 - 1642 - if (evsel__is_bpf_output(evsel)) 1643 - check_pass = true; 1644 - if (attr->type == PERF_TYPE_RAW) 1645 - check_pass = true; 1646 - if (attr->type == PERF_TYPE_HARDWARE) 1647 - check_pass = true; 1648 - if (!check_pass) { 1649 - pr_debug("ERROR: Event type is wrong for map %s\n", name); 1650 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTTYPE; 1651 - } 1652 - 1653 - events = xy->entries / (xy->row_size / xy->entry_size); 1654 - key = *((unsigned int *)pkey); 1655 - if (key >= events) { 1656 - pr_debug("ERROR: there is no event %d for map %s\n", 1657 - key, name); 1658 - return -BPF_LOADER_ERRNO__OBJCONF_MAP_MAPSIZE; 1659 - } 1660 - evt_fd = xyarray__entry(xy, key, 0); 1661 - err = bpf_map_update_elem(map_fd, pkey, evt_fd, BPF_ANY); 1662 - if (err && errno) 1663 - err = -errno; 1664 - return err; 1665 - } 1666 - 1667 - static int 1668 - apply_obj_config_map_for_key(const char *name, int map_fd, 1669 - const struct bpf_map *map, 1670 - struct bpf_map_op *op, 1671 - void *pkey, void *arg __maybe_unused) 1672 - { 1673 - int err; 1674 - 1675 - switch (op->op_type) { 1676 - case BPF_MAP_OP_SET_VALUE: 1677 - err = apply_config_value_for_key(map_fd, pkey, 1678 - bpf_map__value_size(map), 1679 - op->v.value); 1680 - break; 1681 - case BPF_MAP_OP_SET_EVSEL: 1682 - err = apply_config_evsel_for_key(name, map_fd, pkey, 1683 - op->v.evsel); 1684 - break; 1685 - default: 1686 - pr_debug("ERROR: unknown value type for '%s'\n", name); 1687 - err = -BPF_LOADER_ERRNO__INTERNAL; 1688 - } 1689 - return err; 1690 - } 1691 - 1692 - static int 1693 - apply_obj_config_map(struct bpf_map *map) 1694 - { 1695 - return bpf_map_config_foreach_key(map, 1696 - apply_obj_config_map_for_key, 1697 - NULL); 1698 - } 1699 - 1700 - static int 1701 - apply_obj_config_object(struct bpf_object *obj) 1702 - { 1703 - struct bpf_map *map; 1704 - int err; 1705 - 1706 - bpf_object__for_each_map(map, obj) { 1707 - err = apply_obj_config_map(map); 1708 - if (err) 1709 - return err; 1710 - } 1711 - return 0; 1712 - } 1713 - 1714 - int bpf__apply_obj_config(void) 1715 - { 1716 - struct bpf_perf_object *perf_obj, *tmp; 1717 - int err; 1718 - 1719 - bpf_perf_object__for_each(perf_obj, tmp) { 1720 - err = apply_obj_config_object(perf_obj->obj); 1721 - if (err) 1722 - return err; 1723 - } 1724 - 1725 - return 0; 1726 - } 1727 - 1728 - #define bpf__perf_for_each_map(map, pobj, tmp) \ 1729 - bpf_perf_object__for_each(pobj, tmp) \ 1730 - bpf_object__for_each_map(map, pobj->obj) 1731 - 1732 - #define bpf__perf_for_each_map_named(map, pobj, pobjtmp, name) \ 1733 - bpf__perf_for_each_map(map, pobj, pobjtmp) \ 1734 - if (bpf_map__name(map) && (strcmp(name, bpf_map__name(map)) == 0)) 1735 - 1736 - struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name) 1737 - { 1738 - struct bpf_map_priv *tmpl_priv = NULL; 1739 - struct bpf_perf_object *perf_obj, *tmp; 1740 - struct evsel *evsel = NULL; 1741 - struct bpf_map *map; 1742 - int err; 1743 - bool need_init = false; 1744 - 1745 - bpf__perf_for_each_map_named(map, perf_obj, tmp, name) { 1746 - struct bpf_map_priv *priv = map_priv(map); 1747 - 1748 - if (IS_ERR(priv)) 1749 - return ERR_PTR(-BPF_LOADER_ERRNO__INTERNAL); 1750 - 1751 - /* 1752 - * No need to check map type: type should have been 1753 - * verified by kernel. 1754 - */ 1755 - if (!need_init && !priv) 1756 - need_init = !priv; 1757 - if (!tmpl_priv && priv) 1758 - tmpl_priv = priv; 1759 - } 1760 - 1761 - if (!need_init) 1762 - return NULL; 1763 - 1764 - if (!tmpl_priv) { 1765 - char *event_definition = NULL; 1766 - 1767 - if (asprintf(&event_definition, "bpf-output/no-inherit=1,name=%s/", name) < 0) 1768 - return ERR_PTR(-ENOMEM); 1769 - 1770 - err = parse_event(evlist, event_definition); 1771 - free(event_definition); 1772 - 1773 - if (err) { 1774 - pr_debug("ERROR: failed to create the \"%s\" bpf-output event\n", name); 1775 - return ERR_PTR(-err); 1776 - } 1777 - 1778 - evsel = evlist__last(evlist); 1779 - } 1780 - 1781 - bpf__perf_for_each_map_named(map, perf_obj, tmp, name) { 1782 - struct bpf_map_priv *priv = map_priv(map); 1783 - 1784 - if (IS_ERR(priv)) 1785 - return ERR_PTR(-BPF_LOADER_ERRNO__INTERNAL); 1786 - if (priv) 1787 - continue; 1788 - 1789 - if (tmpl_priv) { 1790 - priv = bpf_map_priv__clone(tmpl_priv); 1791 - if (!priv) 1792 - return ERR_PTR(-ENOMEM); 1793 - 1794 - err = map_set_priv(map, priv); 1795 - if (err) { 1796 - bpf_map_priv__clear(map, priv); 1797 - return ERR_PTR(err); 1798 - } 1799 - } else if (evsel) { 1800 - struct bpf_map_op *op; 1801 - 1802 - op = bpf_map__add_newop(map, NULL); 1803 - if (IS_ERR(op)) 1804 - return ERR_CAST(op); 1805 - op->op_type = BPF_MAP_OP_SET_EVSEL; 1806 - op->v.evsel = evsel; 1807 - } 1808 - } 1809 - 1810 - return evsel; 1811 - } 1812 - 1813 - int bpf__setup_stdout(struct evlist *evlist) 1814 - { 1815 - struct evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__"); 1816 - return PTR_ERR_OR_ZERO(evsel); 1817 - } 1818 - 1819 - #define ERRNO_OFFSET(e) ((e) - __BPF_LOADER_ERRNO__START) 1820 - #define ERRCODE_OFFSET(c) ERRNO_OFFSET(BPF_LOADER_ERRNO__##c) 1821 - #define NR_ERRNO (__BPF_LOADER_ERRNO__END - __BPF_LOADER_ERRNO__START) 1822 - 1823 - static const char *bpf_loader_strerror_table[NR_ERRNO] = { 1824 - [ERRCODE_OFFSET(CONFIG)] = "Invalid config string", 1825 - [ERRCODE_OFFSET(GROUP)] = "Invalid group name", 1826 - [ERRCODE_OFFSET(EVENTNAME)] = "No event name found in config string", 1827 - [ERRCODE_OFFSET(INTERNAL)] = "BPF loader internal error", 1828 - [ERRCODE_OFFSET(COMPILE)] = "Error when compiling BPF scriptlet", 1829 - [ERRCODE_OFFSET(PROGCONF_TERM)] = "Invalid program config term in config string", 1830 - [ERRCODE_OFFSET(PROLOGUE)] = "Failed to generate prologue", 1831 - [ERRCODE_OFFSET(PROLOGUE2BIG)] = "Prologue too big for program", 1832 - [ERRCODE_OFFSET(PROLOGUEOOB)] = "Offset out of bound for prologue", 1833 - [ERRCODE_OFFSET(OBJCONF_OPT)] = "Invalid object config option", 1834 - [ERRCODE_OFFSET(OBJCONF_CONF)] = "Config value not set (missing '=')", 1835 - [ERRCODE_OFFSET(OBJCONF_MAP_OPT)] = "Invalid object map config option", 1836 - [ERRCODE_OFFSET(OBJCONF_MAP_NOTEXIST)] = "Target map doesn't exist", 1837 - [ERRCODE_OFFSET(OBJCONF_MAP_VALUE)] = "Incorrect value type for map", 1838 - [ERRCODE_OFFSET(OBJCONF_MAP_TYPE)] = "Incorrect map type", 1839 - [ERRCODE_OFFSET(OBJCONF_MAP_KEYSIZE)] = "Incorrect map key size", 1840 - [ERRCODE_OFFSET(OBJCONF_MAP_VALUESIZE)] = "Incorrect map value size", 1841 - [ERRCODE_OFFSET(OBJCONF_MAP_NOEVT)] = "Event not found for map setting", 1842 - [ERRCODE_OFFSET(OBJCONF_MAP_MAPSIZE)] = "Invalid map size for event setting", 1843 - [ERRCODE_OFFSET(OBJCONF_MAP_EVTDIM)] = "Event dimension too large", 1844 - [ERRCODE_OFFSET(OBJCONF_MAP_EVTINH)] = "Doesn't support inherit event", 1845 - [ERRCODE_OFFSET(OBJCONF_MAP_EVTTYPE)] = "Wrong event type for map", 1846 - [ERRCODE_OFFSET(OBJCONF_MAP_IDX2BIG)] = "Index too large", 1847 - }; 1848 - 1849 - static int 1850 - bpf_loader_strerror(int err, char *buf, size_t size) 1851 - { 1852 - char sbuf[STRERR_BUFSIZE]; 1853 - const char *msg; 1854 - 1855 - if (!buf || !size) 1856 - return -1; 1857 - 1858 - err = err > 0 ? err : -err; 1859 - 1860 - if (err >= __LIBBPF_ERRNO__START) 1861 - return libbpf_strerror(err, buf, size); 1862 - 1863 - if (err >= __BPF_LOADER_ERRNO__START && err < __BPF_LOADER_ERRNO__END) { 1864 - msg = bpf_loader_strerror_table[ERRNO_OFFSET(err)]; 1865 - snprintf(buf, size, "%s", msg); 1866 - buf[size - 1] = '\0'; 1867 - return 0; 1868 - } 1869 - 1870 - if (err >= __BPF_LOADER_ERRNO__END) 1871 - snprintf(buf, size, "Unknown bpf loader error %d", err); 1872 - else 1873 - snprintf(buf, size, "%s", 1874 - str_error_r(err, sbuf, sizeof(sbuf))); 1875 - 1876 - buf[size - 1] = '\0'; 1877 - return -1; 1878 - } 1879 - 1880 - #define bpf__strerror_head(err, buf, size) \ 1881 - char sbuf[STRERR_BUFSIZE], *emsg;\ 1882 - if (!size)\ 1883 - return 0;\ 1884 - if (err < 0)\ 1885 - err = -err;\ 1886 - bpf_loader_strerror(err, sbuf, sizeof(sbuf));\ 1887 - emsg = sbuf;\ 1888 - switch (err) {\ 1889 - default:\ 1890 - scnprintf(buf, size, "%s", emsg);\ 1891 - break; 1892 - 1893 - #define bpf__strerror_entry(val, fmt...)\ 1894 - case val: {\ 1895 - scnprintf(buf, size, fmt);\ 1896 - break;\ 1897 - } 1898 - 1899 - #define bpf__strerror_end(buf, size)\ 1900 - }\ 1901 - buf[size - 1] = '\0'; 1902 - 1903 - int bpf__strerror_prepare_load(const char *filename, bool source, 1904 - int err, char *buf, size_t size) 1905 - { 1906 - size_t n; 1907 - int ret; 1908 - 1909 - n = snprintf(buf, size, "Failed to load %s%s: ", 1910 - filename, source ? " from source" : ""); 1911 - if (n >= size) { 1912 - buf[size - 1] = '\0'; 1913 - return 0; 1914 - } 1915 - buf += n; 1916 - size -= n; 1917 - 1918 - ret = bpf_loader_strerror(err, buf, size); 1919 - buf[size - 1] = '\0'; 1920 - return ret; 1921 - } 1922 - 1923 - int bpf__strerror_probe(struct bpf_object *obj __maybe_unused, 1924 - int err, char *buf, size_t size) 1925 - { 1926 - bpf__strerror_head(err, buf, size); 1927 - case BPF_LOADER_ERRNO__PROGCONF_TERM: { 1928 - scnprintf(buf, size, "%s (add -v to see detail)", emsg); 1929 - break; 1930 - } 1931 - bpf__strerror_entry(EEXIST, "Probe point exist. Try 'perf probe -d \"*\"' and set 'force=yes'"); 1932 - bpf__strerror_entry(EACCES, "You need to be root"); 1933 - bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0"); 1934 - bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file"); 1935 - bpf__strerror_end(buf, size); 1936 - return 0; 1937 - } 1938 - 1939 - int bpf__strerror_load(struct bpf_object *obj, 1940 - int err, char *buf, size_t size) 1941 - { 1942 - bpf__strerror_head(err, buf, size); 1943 - case LIBBPF_ERRNO__KVER: { 1944 - unsigned int obj_kver = bpf_object__kversion(obj); 1945 - unsigned int real_kver; 1946 - 1947 - if (fetch_kernel_version(&real_kver, NULL, 0)) { 1948 - scnprintf(buf, size, "Unable to fetch kernel version"); 1949 - break; 1950 - } 1951 - 1952 - if (obj_kver != real_kver) { 1953 - scnprintf(buf, size, 1954 - "'version' ("KVER_FMT") doesn't match running kernel ("KVER_FMT")", 1955 - KVER_PARAM(obj_kver), 1956 - KVER_PARAM(real_kver)); 1957 - break; 1958 - } 1959 - 1960 - scnprintf(buf, size, "Failed to load program for unknown reason"); 1961 - break; 1962 - } 1963 - bpf__strerror_end(buf, size); 1964 - return 0; 1965 - } 1966 - 1967 - int bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused, 1968 - struct parse_events_term *term __maybe_unused, 1969 - struct evlist *evlist __maybe_unused, 1970 - int *error_pos __maybe_unused, int err, 1971 - char *buf, size_t size) 1972 - { 1973 - bpf__strerror_head(err, buf, size); 1974 - bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE, 1975 - "Can't use this config term with this map type"); 1976 - bpf__strerror_end(buf, size); 1977 - return 0; 1978 - } 1979 - 1980 - int bpf__strerror_apply_obj_config(int err, char *buf, size_t size) 1981 - { 1982 - bpf__strerror_head(err, buf, size); 1983 - bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM, 1984 - "Cannot set event to BPF map in multi-thread tracing"); 1985 - bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH, 1986 - "%s (Hint: use -i to turn off inherit)", emsg); 1987 - bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_EVTTYPE, 1988 - "Can only put raw, hardware and BPF output event into a BPF map"); 1989 - bpf__strerror_end(buf, size); 1990 - return 0; 1991 - } 1992 - 1993 - int bpf__strerror_setup_output_event(struct evlist *evlist __maybe_unused, 1994 - int err, char *buf, size_t size) 1995 - { 1996 - bpf__strerror_head(err, buf, size); 1997 - bpf__strerror_end(buf, size); 1998 - return 0; 1999 - }
-216
tools/perf/util/bpf-loader.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com> 4 - * Copyright (C) 2015, Huawei Inc. 5 - */ 6 - #ifndef __BPF_LOADER_H 7 - #define __BPF_LOADER_H 8 - 9 - #include <linux/compiler.h> 10 - #include <linux/err.h> 11 - 12 - #ifdef HAVE_LIBBPF_SUPPORT 13 - #include <bpf/libbpf.h> 14 - 15 - enum bpf_loader_errno { 16 - __BPF_LOADER_ERRNO__START = __LIBBPF_ERRNO__START - 100, 17 - /* Invalid config string */ 18 - BPF_LOADER_ERRNO__CONFIG = __BPF_LOADER_ERRNO__START, 19 - BPF_LOADER_ERRNO__GROUP, /* Invalid group name */ 20 - BPF_LOADER_ERRNO__EVENTNAME, /* Event name is missing */ 21 - BPF_LOADER_ERRNO__INTERNAL, /* BPF loader internal error */ 22 - BPF_LOADER_ERRNO__COMPILE, /* Error when compiling BPF scriptlet */ 23 - BPF_LOADER_ERRNO__PROGCONF_TERM,/* Invalid program config term in config string */ 24 - BPF_LOADER_ERRNO__PROLOGUE, /* Failed to generate prologue */ 25 - BPF_LOADER_ERRNO__PROLOGUE2BIG, /* Prologue too big for program */ 26 - BPF_LOADER_ERRNO__PROLOGUEOOB, /* Offset out of bound for prologue */ 27 - BPF_LOADER_ERRNO__OBJCONF_OPT, /* Invalid object config option */ 28 - BPF_LOADER_ERRNO__OBJCONF_CONF, /* Config value not set (lost '=')) */ 29 - BPF_LOADER_ERRNO__OBJCONF_MAP_OPT, /* Invalid object map config option */ 30 - BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST, /* Target map not exist */ 31 - BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE, /* Incorrect value type for map */ 32 - BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE, /* Incorrect map type */ 33 - BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE, /* Incorrect map key size */ 34 - BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE,/* Incorrect map value size */ 35 - BPF_LOADER_ERRNO__OBJCONF_MAP_NOEVT, /* Event not found for map setting */ 36 - BPF_LOADER_ERRNO__OBJCONF_MAP_MAPSIZE, /* Invalid map size for event setting */ 37 - BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM, /* Event dimension too large */ 38 - BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH, /* Doesn't support inherit event */ 39 - BPF_LOADER_ERRNO__OBJCONF_MAP_EVTTYPE, /* Wrong event type for map */ 40 - BPF_LOADER_ERRNO__OBJCONF_MAP_IDX2BIG, /* Index too large */ 41 - __BPF_LOADER_ERRNO__END, 42 - }; 43 - #endif // HAVE_LIBBPF_SUPPORT 44 - 45 - struct evsel; 46 - struct evlist; 47 - struct bpf_object; 48 - struct parse_events_term; 49 - #define PERF_BPF_PROBE_GROUP "perf_bpf_probe" 50 - 51 - typedef int (*bpf_prog_iter_callback_t)(const char *group, const char *event, 52 - int fd, struct bpf_object *obj, void *arg); 53 - 54 - #ifdef HAVE_LIBBPF_SUPPORT 55 - struct bpf_object *bpf__prepare_load(const char *filename, bool source); 56 - int bpf__strerror_prepare_load(const char *filename, bool source, 57 - int err, char *buf, size_t size); 58 - 59 - struct bpf_object *bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, 60 - const char *name); 61 - 62 - void bpf__clear(void); 63 - 64 - int bpf__probe(struct bpf_object *obj); 65 - int bpf__unprobe(struct bpf_object *obj); 66 - int bpf__strerror_probe(struct bpf_object *obj, int err, 67 - char *buf, size_t size); 68 - 69 - int bpf__load(struct bpf_object *obj); 70 - int bpf__strerror_load(struct bpf_object *obj, int err, 71 - char *buf, size_t size); 72 - int bpf__foreach_event(struct bpf_object *obj, 73 - bpf_prog_iter_callback_t func, void *arg); 74 - 75 - int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term, 76 - struct evlist *evlist, int *error_pos); 77 - int bpf__strerror_config_obj(struct bpf_object *obj, 78 - struct parse_events_term *term, 79 - struct evlist *evlist, 80 - int *error_pos, int err, char *buf, 81 - size_t size); 82 - int bpf__apply_obj_config(void); 83 - int bpf__strerror_apply_obj_config(int err, char *buf, size_t size); 84 - 85 - int bpf__setup_stdout(struct evlist *evlist); 86 - struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name); 87 - int bpf__strerror_setup_output_event(struct evlist *evlist, int err, char *buf, size_t size); 88 - #else 89 - #include <errno.h> 90 - #include <string.h> 91 - #include "debug.h" 92 - 93 - static inline struct bpf_object * 94 - bpf__prepare_load(const char *filename __maybe_unused, 95 - bool source __maybe_unused) 96 - { 97 - pr_debug("ERROR: eBPF object loading is disabled during compiling.\n"); 98 - return ERR_PTR(-ENOTSUP); 99 - } 100 - 101 - static inline struct bpf_object * 102 - bpf__prepare_load_buffer(void *obj_buf __maybe_unused, 103 - size_t obj_buf_sz __maybe_unused) 104 - { 105 - return ERR_PTR(-ENOTSUP); 106 - } 107 - 108 - static inline void bpf__clear(void) { } 109 - 110 - static inline int bpf__probe(struct bpf_object *obj __maybe_unused) { return 0;} 111 - static inline int bpf__unprobe(struct bpf_object *obj __maybe_unused) { return 0;} 112 - static inline int bpf__load(struct bpf_object *obj __maybe_unused) { return 0; } 113 - 114 - static inline int 115 - bpf__foreach_event(struct bpf_object *obj __maybe_unused, 116 - bpf_prog_iter_callback_t func __maybe_unused, 117 - void *arg __maybe_unused) 118 - { 119 - return 0; 120 - } 121 - 122 - static inline int 123 - bpf__config_obj(struct bpf_object *obj __maybe_unused, 124 - struct parse_events_term *term __maybe_unused, 125 - struct evlist *evlist __maybe_unused, 126 - int *error_pos __maybe_unused) 127 - { 128 - return 0; 129 - } 130 - 131 - static inline int 132 - bpf__apply_obj_config(void) 133 - { 134 - return 0; 135 - } 136 - 137 - static inline int 138 - bpf__setup_stdout(struct evlist *evlist __maybe_unused) 139 - { 140 - return 0; 141 - } 142 - 143 - static inline struct evsel * 144 - bpf__setup_output_event(struct evlist *evlist __maybe_unused, const char *name __maybe_unused) 145 - { 146 - return NULL; 147 - } 148 - 149 - static inline int 150 - __bpf_strerror(char *buf, size_t size) 151 - { 152 - if (!size) 153 - return 0; 154 - strncpy(buf, 155 - "ERROR: eBPF object loading is disabled during compiling.\n", 156 - size); 157 - buf[size - 1] = '\0'; 158 - return 0; 159 - } 160 - 161 - static inline 162 - int bpf__strerror_prepare_load(const char *filename __maybe_unused, 163 - bool source __maybe_unused, 164 - int err __maybe_unused, 165 - char *buf, size_t size) 166 - { 167 - return __bpf_strerror(buf, size); 168 - } 169 - 170 - static inline int 171 - bpf__strerror_probe(struct bpf_object *obj __maybe_unused, 172 - int err __maybe_unused, 173 - char *buf, size_t size) 174 - { 175 - return __bpf_strerror(buf, size); 176 - } 177 - 178 - static inline int bpf__strerror_load(struct bpf_object *obj __maybe_unused, 179 - int err __maybe_unused, 180 - char *buf, size_t size) 181 - { 182 - return __bpf_strerror(buf, size); 183 - } 184 - 185 - static inline int 186 - bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused, 187 - struct parse_events_term *term __maybe_unused, 188 - struct evlist *evlist __maybe_unused, 189 - int *error_pos __maybe_unused, 190 - int err __maybe_unused, 191 - char *buf, size_t size) 192 - { 193 - return __bpf_strerror(buf, size); 194 - } 195 - 196 - static inline int 197 - bpf__strerror_apply_obj_config(int err __maybe_unused, 198 - char *buf, size_t size) 199 - { 200 - return __bpf_strerror(buf, size); 201 - } 202 - 203 - static inline int 204 - bpf__strerror_setup_output_event(struct evlist *evlist __maybe_unused, 205 - int err __maybe_unused, char *buf, size_t size) 206 - { 207 - return __bpf_strerror(buf, size); 208 - } 209 - 210 - #endif 211 - 212 - static inline int bpf__strerror_setup_stdout(struct evlist *evlist, int err, char *buf, size_t size) 213 - { 214 - return bpf__strerror_setup_output_event(evlist, err, buf, size); 215 - } 216 - #endif
-4
tools/perf/util/config.c
··· 16 16 #include <subcmd/exec-cmd.h> 17 17 #include "util/event.h" /* proc_map_timeout */ 18 18 #include "util/hist.h" /* perf_hist_config */ 19 - #include "util/llvm-utils.h" /* perf_llvm_config */ 20 19 #include "util/stat.h" /* perf_stat__set_big_num */ 21 20 #include "util/evsel.h" /* evsel__hw_names, evsel__use_bpf_counters */ 22 21 #include "util/srcline.h" /* addr2line_timeout_ms */ ··· 484 485 485 486 if (strstarts(var, "call-graph.")) 486 487 return perf_callchain_config(var, value); 487 - 488 - if (strstarts(var, "llvm.")) 489 - return perf_llvm_config(var, value); 490 488 491 489 if (strstarts(var, "buildid.")) 492 490 return perf_buildid_config(var, value);
-612
tools/perf/util/llvm-utils.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com> 4 - * Copyright (C) 2015, Huawei Inc. 5 - */ 6 - 7 - #include <errno.h> 8 - #include <limits.h> 9 - #include <stdio.h> 10 - #include <stdlib.h> 11 - #include <unistd.h> 12 - #include <linux/err.h> 13 - #include <linux/string.h> 14 - #include <linux/zalloc.h> 15 - #include "debug.h" 16 - #include "llvm-utils.h" 17 - #include "config.h" 18 - #include "util.h" 19 - #include <sys/wait.h> 20 - #include <subcmd/exec-cmd.h> 21 - 22 - #define CLANG_BPF_CMD_DEFAULT_TEMPLATE \ 23 - "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\ 24 - "-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE " \ 25 - "$CLANG_OPTIONS $PERF_BPF_INC_OPTIONS $KERNEL_INC_OPTIONS " \ 26 - "-Wno-unused-value -Wno-pointer-sign " \ 27 - "-working-directory $WORKING_DIR " \ 28 - "-c \"$CLANG_SOURCE\" --target=bpf $CLANG_EMIT_LLVM -g -O2 -o - $LLVM_OPTIONS_PIPE" 29 - 30 - struct llvm_param llvm_param = { 31 - .clang_path = "clang", 32 - .llc_path = "llc", 33 - .clang_bpf_cmd_template = CLANG_BPF_CMD_DEFAULT_TEMPLATE, 34 - .clang_opt = NULL, 35 - .opts = NULL, 36 - .kbuild_dir = NULL, 37 - .kbuild_opts = NULL, 38 - .user_set_param = false, 39 - }; 40 - 41 - static void version_notice(void); 42 - 43 - int perf_llvm_config(const char *var, const char *value) 44 - { 45 - if (!strstarts(var, "llvm.")) 46 - return 0; 47 - var += sizeof("llvm.") - 1; 48 - 49 - if (!strcmp(var, "clang-path")) 50 - llvm_param.clang_path = strdup(value); 51 - else if (!strcmp(var, "clang-bpf-cmd-template")) 52 - llvm_param.clang_bpf_cmd_template = strdup(value); 53 - else if (!strcmp(var, "clang-opt")) 54 - llvm_param.clang_opt = strdup(value); 55 - else if (!strcmp(var, "kbuild-dir")) 56 - llvm_param.kbuild_dir = strdup(value); 57 - else if (!strcmp(var, "kbuild-opts")) 58 - llvm_param.kbuild_opts = strdup(value); 59 - else if (!strcmp(var, "dump-obj")) 60 - llvm_param.dump_obj = !!perf_config_bool(var, value); 61 - else if (!strcmp(var, "opts")) 62 - llvm_param.opts = strdup(value); 63 - else { 64 - pr_debug("Invalid LLVM config option: %s\n", value); 65 - return -1; 66 - } 67 - llvm_param.user_set_param = true; 68 - return 0; 69 - } 70 - 71 - static int 72 - search_program(const char *def, const char *name, 73 - char *output) 74 - { 75 - char *env, *path, *tmp = NULL; 76 - char buf[PATH_MAX]; 77 - int ret; 78 - 79 - output[0] = '\0'; 80 - if (def && def[0] != '\0') { 81 - if (def[0] == '/') { 82 - if (access(def, F_OK) == 0) { 83 - strlcpy(output, def, PATH_MAX); 84 - return 0; 85 - } 86 - } else if (def[0] != '\0') 87 - name = def; 88 - } 89 - 90 - env = getenv("PATH"); 91 - if (!env) 92 - return -1; 93 - env = strdup(env); 94 - if (!env) 95 - return -1; 96 - 97 - ret = -ENOENT; 98 - path = strtok_r(env, ":", &tmp); 99 - while (path) { 100 - scnprintf(buf, sizeof(buf), "%s/%s", path, name); 101 - if (access(buf, F_OK) == 0) { 102 - strlcpy(output, buf, PATH_MAX); 103 - ret = 0; 104 - break; 105 - } 106 - path = strtok_r(NULL, ":", &tmp); 107 - } 108 - 109 - free(env); 110 - return ret; 111 - } 112 - 113 - static int search_program_and_warn(const char *def, const char *name, 114 - char *output) 115 - { 116 - int ret = search_program(def, name, output); 117 - 118 - if (ret) { 119 - pr_err("ERROR:\tunable to find %s.\n" 120 - "Hint:\tTry to install latest clang/llvm to support BPF. Check your $PATH\n" 121 - " \tand '%s-path' option in [llvm] section of ~/.perfconfig.\n", 122 - name, name); 123 - version_notice(); 124 - } 125 - return ret; 126 - } 127 - 128 - #define READ_SIZE 4096 129 - static int 130 - read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz) 131 - { 132 - int err = 0; 133 - void *buf = NULL; 134 - FILE *file = NULL; 135 - size_t read_sz = 0, buf_sz = 0; 136 - char serr[STRERR_BUFSIZE]; 137 - 138 - file = popen(cmd, "r"); 139 - if (!file) { 140 - pr_err("ERROR: unable to popen cmd: %s\n", 141 - str_error_r(errno, serr, sizeof(serr))); 142 - return -EINVAL; 143 - } 144 - 145 - while (!feof(file) && !ferror(file)) { 146 - /* 147 - * Make buf_sz always have obe byte extra space so we 148 - * can put '\0' there. 149 - */ 150 - if (buf_sz - read_sz < READ_SIZE + 1) { 151 - void *new_buf; 152 - 153 - buf_sz = read_sz + READ_SIZE + 1; 154 - new_buf = realloc(buf, buf_sz); 155 - 156 - if (!new_buf) { 157 - pr_err("ERROR: failed to realloc memory\n"); 158 - err = -ENOMEM; 159 - goto errout; 160 - } 161 - 162 - buf = new_buf; 163 - } 164 - read_sz += fread(buf + read_sz, 1, READ_SIZE, file); 165 - } 166 - 167 - if (buf_sz - read_sz < 1) { 168 - pr_err("ERROR: internal error\n"); 169 - err = -EINVAL; 170 - goto errout; 171 - } 172 - 173 - if (ferror(file)) { 174 - pr_err("ERROR: error occurred when reading from pipe: %s\n", 175 - str_error_r(errno, serr, sizeof(serr))); 176 - err = -EIO; 177 - goto errout; 178 - } 179 - 180 - err = WEXITSTATUS(pclose(file)); 181 - file = NULL; 182 - if (err) { 183 - err = -EINVAL; 184 - goto errout; 185 - } 186 - 187 - /* 188 - * If buf is string, give it terminal '\0' to make our life 189 - * easier. If buf is not string, that '\0' is out of space 190 - * indicated by read_sz so caller won't even notice it. 191 - */ 192 - ((char *)buf)[read_sz] = '\0'; 193 - 194 - if (!p_buf) 195 - free(buf); 196 - else 197 - *p_buf = buf; 198 - 199 - if (p_read_sz) 200 - *p_read_sz = read_sz; 201 - return 0; 202 - 203 - errout: 204 - if (file) 205 - pclose(file); 206 - free(buf); 207 - if (p_buf) 208 - *p_buf = NULL; 209 - if (p_read_sz) 210 - *p_read_sz = 0; 211 - return err; 212 - } 213 - 214 - static inline void 215 - force_set_env(const char *var, const char *value) 216 - { 217 - if (value) { 218 - setenv(var, value, 1); 219 - pr_debug("set env: %s=%s\n", var, value); 220 - } else { 221 - unsetenv(var); 222 - pr_debug("unset env: %s\n", var); 223 - } 224 - } 225 - 226 - static void 227 - version_notice(void) 228 - { 229 - pr_err( 230 - " \tLLVM 3.7 or newer is required. Which can be found from http://llvm.org\n" 231 - " \tYou may want to try git trunk:\n" 232 - " \t\tgit clone http://llvm.org/git/llvm.git\n" 233 - " \t\t and\n" 234 - " \t\tgit clone http://llvm.org/git/clang.git\n\n" 235 - " \tOr fetch the latest clang/llvm 3.7 from pre-built llvm packages for\n" 236 - " \tdebian/ubuntu:\n" 237 - " \t\thttps://apt.llvm.org/\n\n" 238 - " \tIf you are using old version of clang, change 'clang-bpf-cmd-template'\n" 239 - " \toption in [llvm] section of ~/.perfconfig to:\n\n" 240 - " \t \"$CLANG_EXEC $CLANG_OPTIONS $KERNEL_INC_OPTIONS $PERF_BPF_INC_OPTIONS \\\n" 241 - " \t -working-directory $WORKING_DIR -c $CLANG_SOURCE \\\n" 242 - " \t -emit-llvm -o - | /path/to/llc -march=bpf -filetype=obj -o -\"\n" 243 - " \t(Replace /path/to/llc with path to your llc)\n\n" 244 - ); 245 - } 246 - 247 - static int detect_kbuild_dir(char **kbuild_dir) 248 - { 249 - const char *test_dir = llvm_param.kbuild_dir; 250 - const char *prefix_dir = ""; 251 - const char *suffix_dir = ""; 252 - 253 - /* _UTSNAME_LENGTH is 65 */ 254 - char release[128]; 255 - 256 - char *autoconf_path; 257 - 258 - int err; 259 - 260 - if (!test_dir) { 261 - err = fetch_kernel_version(NULL, release, 262 - sizeof(release)); 263 - if (err) 264 - return -EINVAL; 265 - 266 - test_dir = release; 267 - prefix_dir = "/lib/modules/"; 268 - suffix_dir = "/build"; 269 - } 270 - 271 - err = asprintf(&autoconf_path, "%s%s%s/include/generated/autoconf.h", 272 - prefix_dir, test_dir, suffix_dir); 273 - if (err < 0) 274 - return -ENOMEM; 275 - 276 - if (access(autoconf_path, R_OK) == 0) { 277 - free(autoconf_path); 278 - 279 - err = asprintf(kbuild_dir, "%s%s%s", prefix_dir, test_dir, 280 - suffix_dir); 281 - if (err < 0) 282 - return -ENOMEM; 283 - return 0; 284 - } 285 - pr_debug("%s: Couldn't find \"%s\", missing kernel-devel package?.\n", 286 - __func__, autoconf_path); 287 - free(autoconf_path); 288 - return -ENOENT; 289 - } 290 - 291 - static const char *kinc_fetch_script = 292 - "#!/usr/bin/env sh\n" 293 - "if ! test -d \"$KBUILD_DIR\"\n" 294 - "then\n" 295 - " exit 1\n" 296 - "fi\n" 297 - "if ! test -f \"$KBUILD_DIR/include/generated/autoconf.h\"\n" 298 - "then\n" 299 - " exit 1\n" 300 - "fi\n" 301 - "TMPDIR=`mktemp -d`\n" 302 - "if test -z \"$TMPDIR\"\n" 303 - "then\n" 304 - " exit 1\n" 305 - "fi\n" 306 - "cat << EOF > $TMPDIR/Makefile\n" 307 - "obj-y := dummy.o\n" 308 - "\\$(obj)/%.o: \\$(src)/%.c\n" 309 - "\t@echo -n \"\\$(NOSTDINC_FLAGS) \\$(LINUXINCLUDE) \\$(EXTRA_CFLAGS)\"\n" 310 - "\t\\$(CC) -c -o \\$@ \\$<\n" 311 - "EOF\n" 312 - "touch $TMPDIR/dummy.c\n" 313 - "make -s -C $KBUILD_DIR M=$TMPDIR $KBUILD_OPTS dummy.o 2>/dev/null\n" 314 - "RET=$?\n" 315 - "rm -rf $TMPDIR\n" 316 - "exit $RET\n"; 317 - 318 - void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts) 319 - { 320 - static char *saved_kbuild_dir; 321 - static char *saved_kbuild_include_opts; 322 - int err; 323 - 324 - if (!kbuild_dir || !kbuild_include_opts) 325 - return; 326 - 327 - *kbuild_dir = NULL; 328 - *kbuild_include_opts = NULL; 329 - 330 - if (saved_kbuild_dir && saved_kbuild_include_opts && 331 - !IS_ERR(saved_kbuild_dir) && !IS_ERR(saved_kbuild_include_opts)) { 332 - *kbuild_dir = strdup(saved_kbuild_dir); 333 - *kbuild_include_opts = strdup(saved_kbuild_include_opts); 334 - 335 - if (*kbuild_dir && *kbuild_include_opts) 336 - return; 337 - 338 - zfree(kbuild_dir); 339 - zfree(kbuild_include_opts); 340 - /* 341 - * Don't fall through: it may breaks saved_kbuild_dir and 342 - * saved_kbuild_include_opts if detect them again when 343 - * memory is low. 344 - */ 345 - return; 346 - } 347 - 348 - if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) { 349 - pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n"); 350 - pr_debug("Skip kbuild options detection.\n"); 351 - goto errout; 352 - } 353 - 354 - err = detect_kbuild_dir(kbuild_dir); 355 - if (err) { 356 - pr_warning( 357 - "WARNING:\tunable to get correct kernel building directory.\n" 358 - "Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]\n" 359 - " \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild\n" 360 - " \tdetection.\n\n"); 361 - goto errout; 362 - } 363 - 364 - pr_debug("Kernel build dir is set to %s\n", *kbuild_dir); 365 - force_set_env("KBUILD_DIR", *kbuild_dir); 366 - force_set_env("KBUILD_OPTS", llvm_param.kbuild_opts); 367 - err = read_from_pipe(kinc_fetch_script, 368 - (void **)kbuild_include_opts, 369 - NULL); 370 - if (err) { 371 - pr_warning( 372 - "WARNING:\tunable to get kernel include directories from '%s'\n" 373 - "Hint:\tTry set clang include options using 'clang-bpf-cmd-template'\n" 374 - " \toption in [llvm] section of ~/.perfconfig and set 'kbuild-dir'\n" 375 - " \toption in [llvm] to \"\" to suppress this detection.\n\n", 376 - *kbuild_dir); 377 - 378 - zfree(kbuild_dir); 379 - goto errout; 380 - } 381 - 382 - pr_debug("include option is set to %s\n", *kbuild_include_opts); 383 - 384 - saved_kbuild_dir = strdup(*kbuild_dir); 385 - saved_kbuild_include_opts = strdup(*kbuild_include_opts); 386 - 387 - if (!saved_kbuild_dir || !saved_kbuild_include_opts) { 388 - zfree(&saved_kbuild_dir); 389 - zfree(&saved_kbuild_include_opts); 390 - } 391 - return; 392 - errout: 393 - saved_kbuild_dir = ERR_PTR(-EINVAL); 394 - saved_kbuild_include_opts = ERR_PTR(-EINVAL); 395 - } 396 - 397 - int llvm__get_nr_cpus(void) 398 - { 399 - static int nr_cpus_avail = 0; 400 - char serr[STRERR_BUFSIZE]; 401 - 402 - if (nr_cpus_avail > 0) 403 - return nr_cpus_avail; 404 - 405 - nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); 406 - if (nr_cpus_avail <= 0) { 407 - pr_err( 408 - "WARNING:\tunable to get available CPUs in this system: %s\n" 409 - " \tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr))); 410 - nr_cpus_avail = 128; 411 - } 412 - return nr_cpus_avail; 413 - } 414 - 415 - void llvm__dump_obj(const char *path, void *obj_buf, size_t size) 416 - { 417 - char *obj_path = strdup(path); 418 - FILE *fp; 419 - char *p; 420 - 421 - if (!obj_path) { 422 - pr_warning("WARNING: Not enough memory, skip object dumping\n"); 423 - return; 424 - } 425 - 426 - p = strrchr(obj_path, '.'); 427 - if (!p || (strcmp(p, ".c") != 0)) { 428 - pr_warning("WARNING: invalid llvm source path: '%s', skip object dumping\n", 429 - obj_path); 430 - goto out; 431 - } 432 - 433 - p[1] = 'o'; 434 - fp = fopen(obj_path, "wb"); 435 - if (!fp) { 436 - pr_warning("WARNING: failed to open '%s': %s, skip object dumping\n", 437 - obj_path, strerror(errno)); 438 - goto out; 439 - } 440 - 441 - pr_debug("LLVM: dumping %s\n", obj_path); 442 - if (fwrite(obj_buf, size, 1, fp) != 1) 443 - pr_debug("WARNING: failed to write to file '%s': %s, skip object dumping\n", obj_path, strerror(errno)); 444 - fclose(fp); 445 - out: 446 - free(obj_path); 447 - } 448 - 449 - int llvm__compile_bpf(const char *path, void **p_obj_buf, 450 - size_t *p_obj_buf_sz) 451 - { 452 - size_t obj_buf_sz; 453 - void *obj_buf = NULL; 454 - int err, nr_cpus_avail; 455 - unsigned int kernel_version; 456 - char linux_version_code_str[64]; 457 - const char *clang_opt = llvm_param.clang_opt; 458 - char clang_path[PATH_MAX], llc_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64]; 459 - char serr[STRERR_BUFSIZE]; 460 - char *kbuild_dir = NULL, *kbuild_include_opts = NULL, 461 - *perf_bpf_include_opts = NULL; 462 - const char *template = llvm_param.clang_bpf_cmd_template; 463 - char *pipe_template = NULL; 464 - const char *opts = llvm_param.opts; 465 - char *command_echo = NULL, *command_out; 466 - char *libbpf_include_dir = system_path(LIBBPF_INCLUDE_DIR); 467 - 468 - if (path[0] != '-' && realpath(path, abspath) == NULL) { 469 - err = errno; 470 - pr_err("ERROR: problems with path %s: %s\n", 471 - path, str_error_r(err, serr, sizeof(serr))); 472 - return -err; 473 - } 474 - 475 - if (!template) 476 - template = CLANG_BPF_CMD_DEFAULT_TEMPLATE; 477 - 478 - err = search_program_and_warn(llvm_param.clang_path, 479 - "clang", clang_path); 480 - if (err) 481 - return -ENOENT; 482 - 483 - /* 484 - * This is an optional work. Even it fail we can continue our 485 - * work. Needn't check error return. 486 - */ 487 - llvm__get_kbuild_opts(&kbuild_dir, &kbuild_include_opts); 488 - 489 - nr_cpus_avail = llvm__get_nr_cpus(); 490 - snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d", 491 - nr_cpus_avail); 492 - 493 - if (fetch_kernel_version(&kernel_version, NULL, 0)) 494 - kernel_version = 0; 495 - 496 - snprintf(linux_version_code_str, sizeof(linux_version_code_str), 497 - "0x%x", kernel_version); 498 - if (asprintf(&perf_bpf_include_opts, "-I%s/", libbpf_include_dir) < 0) 499 - goto errout; 500 - force_set_env("NR_CPUS", nr_cpus_avail_str); 501 - force_set_env("LINUX_VERSION_CODE", linux_version_code_str); 502 - force_set_env("CLANG_EXEC", clang_path); 503 - force_set_env("CLANG_OPTIONS", clang_opt); 504 - force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts); 505 - force_set_env("PERF_BPF_INC_OPTIONS", perf_bpf_include_opts); 506 - force_set_env("WORKING_DIR", kbuild_dir ? : "."); 507 - 508 - if (opts) { 509 - err = search_program_and_warn(llvm_param.llc_path, "llc", llc_path); 510 - if (err) 511 - goto errout; 512 - 513 - err = -ENOMEM; 514 - if (asprintf(&pipe_template, "%s -emit-llvm | %s -march=bpf %s -filetype=obj -o -", 515 - template, llc_path, opts) < 0) { 516 - pr_err("ERROR:\tnot enough memory to setup command line\n"); 517 - goto errout; 518 - } 519 - 520 - template = pipe_template; 521 - 522 - } 523 - 524 - /* 525 - * Since we may reset clang's working dir, path of source file 526 - * should be transferred into absolute path, except we want 527 - * stdin to be source file (testing). 528 - */ 529 - force_set_env("CLANG_SOURCE", 530 - (path[0] == '-') ? path : abspath); 531 - 532 - pr_debug("llvm compiling command template: %s\n", template); 533 - 534 - /* 535 - * Below, substitute control characters for values that can cause the 536 - * echo to misbehave, then substitute the values back. 537 - */ 538 - err = -ENOMEM; 539 - if (asprintf(&command_echo, "echo -n \a%s\a", template) < 0) 540 - goto errout; 541 - 542 - #define SWAP_CHAR(a, b) do { if (*p == a) *p = b; } while (0) 543 - for (char *p = command_echo; *p; p++) { 544 - SWAP_CHAR('<', '\001'); 545 - SWAP_CHAR('>', '\002'); 546 - SWAP_CHAR('"', '\003'); 547 - SWAP_CHAR('\'', '\004'); 548 - SWAP_CHAR('|', '\005'); 549 - SWAP_CHAR('&', '\006'); 550 - SWAP_CHAR('\a', '"'); 551 - } 552 - err = read_from_pipe(command_echo, (void **) &command_out, NULL); 553 - if (err) 554 - goto errout; 555 - 556 - for (char *p = command_out; *p; p++) { 557 - SWAP_CHAR('\001', '<'); 558 - SWAP_CHAR('\002', '>'); 559 - SWAP_CHAR('\003', '"'); 560 - SWAP_CHAR('\004', '\''); 561 - SWAP_CHAR('\005', '|'); 562 - SWAP_CHAR('\006', '&'); 563 - } 564 - #undef SWAP_CHAR 565 - pr_debug("llvm compiling command : %s\n", command_out); 566 - 567 - err = read_from_pipe(template, &obj_buf, &obj_buf_sz); 568 - if (err) { 569 - pr_err("ERROR:\tunable to compile %s\n", path); 570 - pr_err("Hint:\tCheck error message shown above.\n"); 571 - pr_err("Hint:\tYou can also pre-compile it into .o using:\n"); 572 - pr_err(" \t\tclang --target=bpf -O2 -c %s\n", path); 573 - pr_err(" \twith proper -I and -D options.\n"); 574 - goto errout; 575 - } 576 - 577 - free(command_echo); 578 - free(command_out); 579 - free(kbuild_dir); 580 - free(kbuild_include_opts); 581 - free(perf_bpf_include_opts); 582 - free(libbpf_include_dir); 583 - 584 - if (!p_obj_buf) 585 - free(obj_buf); 586 - else 587 - *p_obj_buf = obj_buf; 588 - 589 - if (p_obj_buf_sz) 590 - *p_obj_buf_sz = obj_buf_sz; 591 - return 0; 592 - errout: 593 - free(command_echo); 594 - free(kbuild_dir); 595 - free(kbuild_include_opts); 596 - free(obj_buf); 597 - free(perf_bpf_include_opts); 598 - free(libbpf_include_dir); 599 - free(pipe_template); 600 - if (p_obj_buf) 601 - *p_obj_buf = NULL; 602 - if (p_obj_buf_sz) 603 - *p_obj_buf_sz = 0; 604 - return err; 605 - } 606 - 607 - int llvm__search_clang(void) 608 - { 609 - char clang_path[PATH_MAX]; 610 - 611 - return search_program_and_warn(llvm_param.clang_path, "clang", clang_path); 612 - }
-69
tools/perf/util/llvm-utils.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com> 4 - * Copyright (C) 2015, Huawei Inc. 5 - */ 6 - #ifndef __LLVM_UTILS_H 7 - #define __LLVM_UTILS_H 8 - 9 - #include <stdbool.h> 10 - 11 - struct llvm_param { 12 - /* Path of clang executable */ 13 - const char *clang_path; 14 - /* Path of llc executable */ 15 - const char *llc_path; 16 - /* 17 - * Template of clang bpf compiling. 5 env variables 18 - * can be used: 19 - * $CLANG_EXEC: Path to clang. 20 - * $CLANG_OPTIONS: Extra options to clang. 21 - * $KERNEL_INC_OPTIONS: Kernel include directories. 22 - * $WORKING_DIR: Kernel source directory. 23 - * $CLANG_SOURCE: Source file to be compiled. 24 - */ 25 - const char *clang_bpf_cmd_template; 26 - /* Will be filled in $CLANG_OPTIONS */ 27 - const char *clang_opt; 28 - /* 29 - * If present it'll add -emit-llvm to $CLANG_OPTIONS to pipe 30 - * the clang output to llc, useful for new llvm options not 31 - * yet selectable via 'clang -mllvm option', such as -mattr=dwarfris 32 - * in clang 6.0/llvm 7 33 - */ 34 - const char *opts; 35 - /* Where to find kbuild system */ 36 - const char *kbuild_dir; 37 - /* 38 - * Arguments passed to make, like 'ARCH=arm' if doing cross 39 - * compiling. Should not be used for dynamic compiling. 40 - */ 41 - const char *kbuild_opts; 42 - /* 43 - * Default is false. If set to true, write compiling result 44 - * to object file. 45 - */ 46 - bool dump_obj; 47 - /* 48 - * Default is false. If one of the above fields is set by user 49 - * explicitly then user_set_llvm is set to true. This is used 50 - * for perf test. If user doesn't set anything in .perfconfig 51 - * and clang is not found, don't trigger llvm test. 52 - */ 53 - bool user_set_param; 54 - }; 55 - 56 - extern struct llvm_param llvm_param; 57 - int perf_llvm_config(const char *var, const char *value); 58 - 59 - int llvm__compile_bpf(const char *path, void **p_obj_buf, size_t *p_obj_buf_sz); 60 - 61 - /* This function is for test__llvm() use only */ 62 - int llvm__search_clang(void); 63 - 64 - /* Following functions are reused by builtin clang support */ 65 - void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts); 66 - int llvm__get_nr_cpus(void); 67 - 68 - void llvm__dump_obj(const char *path, void *obj_buf, size_t size); 69 - #endif
-268
tools/perf/util/parse-events.c
··· 14 14 #include "parse-events.h" 15 15 #include "string2.h" 16 16 #include "strlist.h" 17 - #include "bpf-loader.h" 18 17 #include "debug.h" 19 18 #include <api/fs/tracing_path.h> 20 19 #include <perf/cpumap.h> ··· 646 647 return ret; 647 648 } 648 649 #endif /* HAVE_LIBTRACEEVENT */ 649 - 650 - #ifdef HAVE_LIBBPF_SUPPORT 651 - struct __add_bpf_event_param { 652 - struct parse_events_state *parse_state; 653 - struct list_head *list; 654 - struct list_head *head_config; 655 - YYLTYPE *loc; 656 - }; 657 - 658 - static int add_bpf_event(const char *group, const char *event, int fd, struct bpf_object *obj, 659 - void *_param) 660 - { 661 - LIST_HEAD(new_evsels); 662 - struct __add_bpf_event_param *param = _param; 663 - struct parse_events_state *parse_state = param->parse_state; 664 - struct list_head *list = param->list; 665 - struct evsel *pos; 666 - int err; 667 - /* 668 - * Check if we should add the event, i.e. if it is a TP but starts with a '!', 669 - * then don't add the tracepoint, this will be used for something else, like 670 - * adding to a BPF_MAP_TYPE_PROG_ARRAY. 671 - * 672 - * See tools/perf/examples/bpf/augmented_raw_syscalls.c 673 - */ 674 - if (group[0] == '!') 675 - return 0; 676 - 677 - pr_debug("add bpf event %s:%s and attach bpf program %d\n", 678 - group, event, fd); 679 - 680 - err = parse_events_add_tracepoint(&new_evsels, &parse_state->idx, group, 681 - event, parse_state->error, 682 - param->head_config, param->loc); 683 - if (err) { 684 - struct evsel *evsel, *tmp; 685 - 686 - pr_debug("Failed to add BPF event %s:%s\n", 687 - group, event); 688 - list_for_each_entry_safe(evsel, tmp, &new_evsels, core.node) { 689 - list_del_init(&evsel->core.node); 690 - evsel__delete(evsel); 691 - } 692 - return err; 693 - } 694 - pr_debug("adding %s:%s\n", group, event); 695 - 696 - list_for_each_entry(pos, &new_evsels, core.node) { 697 - pr_debug("adding %s:%s to %p\n", 698 - group, event, pos); 699 - pos->bpf_fd = fd; 700 - pos->bpf_obj = obj; 701 - } 702 - list_splice(&new_evsels, list); 703 - return 0; 704 - } 705 - 706 - int parse_events_load_bpf_obj(struct parse_events_state *parse_state, 707 - struct list_head *list, 708 - struct bpf_object *obj, 709 - struct list_head *head_config, 710 - void *loc) 711 - { 712 - int err; 713 - char errbuf[BUFSIZ]; 714 - struct __add_bpf_event_param param = {parse_state, list, head_config, loc}; 715 - static bool registered_unprobe_atexit = false; 716 - YYLTYPE test_loc = {.first_column = -1}; 717 - 718 - if (IS_ERR(obj) || !obj) { 719 - snprintf(errbuf, sizeof(errbuf), 720 - "Internal error: load bpf obj with NULL"); 721 - err = -EINVAL; 722 - goto errout; 723 - } 724 - 725 - /* 726 - * Register atexit handler before calling bpf__probe() so 727 - * bpf__probe() don't need to unprobe probe points its already 728 - * created when failure. 729 - */ 730 - if (!registered_unprobe_atexit) { 731 - atexit(bpf__clear); 732 - registered_unprobe_atexit = true; 733 - } 734 - 735 - err = bpf__probe(obj); 736 - if (err) { 737 - bpf__strerror_probe(obj, err, errbuf, sizeof(errbuf)); 738 - goto errout; 739 - } 740 - 741 - err = bpf__load(obj); 742 - if (err) { 743 - bpf__strerror_load(obj, err, errbuf, sizeof(errbuf)); 744 - goto errout; 745 - } 746 - 747 - if (!param.loc) 748 - param.loc = &test_loc; 749 - 750 - err = bpf__foreach_event(obj, add_bpf_event, &param); 751 - if (err) { 752 - snprintf(errbuf, sizeof(errbuf), 753 - "Attach events in BPF object failed"); 754 - goto errout; 755 - } 756 - 757 - return 0; 758 - errout: 759 - parse_events_error__handle(parse_state->error, param.loc ? param.loc->first_column : 0, 760 - strdup(errbuf), strdup("(add -v to see detail)")); 761 - return err; 762 - } 763 - 764 - static int 765 - parse_events_config_bpf(struct parse_events_state *parse_state, 766 - struct bpf_object *obj, 767 - struct list_head *head_config) 768 - { 769 - struct parse_events_term *term; 770 - int error_pos = 0; 771 - 772 - if (!head_config || list_empty(head_config)) 773 - return 0; 774 - 775 - list_for_each_entry(term, head_config, list) { 776 - int err; 777 - 778 - if (term->type_term != PARSE_EVENTS__TERM_TYPE_USER) { 779 - parse_events_error__handle(parse_state->error, term->err_term, 780 - strdup("Invalid config term for BPF object"), 781 - NULL); 782 - return -EINVAL; 783 - } 784 - 785 - err = bpf__config_obj(obj, term, parse_state->evlist, &error_pos); 786 - if (err) { 787 - char errbuf[BUFSIZ]; 788 - int idx; 789 - 790 - bpf__strerror_config_obj(obj, term, parse_state->evlist, 791 - &error_pos, err, errbuf, 792 - sizeof(errbuf)); 793 - 794 - if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE) 795 - idx = term->err_val; 796 - else 797 - idx = term->err_term + error_pos; 798 - 799 - parse_events_error__handle(parse_state->error, idx, 800 - strdup(errbuf), 801 - NULL); 802 - return err; 803 - } 804 - } 805 - return 0; 806 - } 807 - 808 - /* 809 - * Split config terms: 810 - * perf record -e bpf.c/call-graph=fp,map:array.value[0]=1/ ... 811 - * 'call-graph=fp' is 'evt config', should be applied to each 812 - * events in bpf.c. 813 - * 'map:array.value[0]=1' is 'obj config', should be processed 814 - * with parse_events_config_bpf. 815 - * 816 - * Move object config terms from the first list to obj_head_config. 817 - */ 818 - static void 819 - split_bpf_config_terms(struct list_head *evt_head_config, 820 - struct list_head *obj_head_config) 821 - { 822 - struct parse_events_term *term, *temp; 823 - 824 - /* 825 - * Currently, all possible user config term 826 - * belong to bpf object. parse_events__is_hardcoded_term() 827 - * happens to be a good flag. 828 - * 829 - * See parse_events_config_bpf() and 830 - * config_term_tracepoint(). 831 - */ 832 - list_for_each_entry_safe(term, temp, evt_head_config, list) 833 - if (!parse_events__is_hardcoded_term(term)) 834 - list_move_tail(&term->list, obj_head_config); 835 - } 836 - 837 - int parse_events_load_bpf(struct parse_events_state *parse_state, 838 - struct list_head *list, 839 - char *bpf_file_name, 840 - bool source, 841 - struct list_head *head_config, 842 - void *loc_) 843 - { 844 - int err; 845 - struct bpf_object *obj; 846 - LIST_HEAD(obj_head_config); 847 - YYLTYPE *loc = loc_; 848 - 849 - if (head_config) 850 - split_bpf_config_terms(head_config, &obj_head_config); 851 - 852 - obj = bpf__prepare_load(bpf_file_name, source); 853 - if (IS_ERR(obj)) { 854 - char errbuf[BUFSIZ]; 855 - 856 - err = PTR_ERR(obj); 857 - 858 - if (err == -ENOTSUP) 859 - snprintf(errbuf, sizeof(errbuf), 860 - "BPF support is not compiled"); 861 - else 862 - bpf__strerror_prepare_load(bpf_file_name, 863 - source, 864 - -err, errbuf, 865 - sizeof(errbuf)); 866 - 867 - parse_events_error__handle(parse_state->error, loc->first_column, 868 - strdup(errbuf), strdup("(add -v to see detail)")); 869 - return err; 870 - } 871 - 872 - err = parse_events_load_bpf_obj(parse_state, list, obj, head_config, loc); 873 - if (err) 874 - return err; 875 - err = parse_events_config_bpf(parse_state, obj, &obj_head_config); 876 - 877 - /* 878 - * Caller doesn't know anything about obj_head_config, 879 - * so combine them together again before returning. 880 - */ 881 - if (head_config) 882 - list_splice_tail(&obj_head_config, head_config); 883 - return err; 884 - } 885 - #else // HAVE_LIBBPF_SUPPORT 886 - int parse_events_load_bpf_obj(struct parse_events_state *parse_state, 887 - struct list_head *list __maybe_unused, 888 - struct bpf_object *obj __maybe_unused, 889 - struct list_head *head_config __maybe_unused, 890 - void *loc_) 891 - { 892 - YYLTYPE *loc = loc_; 893 - 894 - parse_events_error__handle(parse_state->error, loc->first_column, 895 - strdup("BPF support is not compiled"), 896 - strdup("Make sure libbpf-devel is available at build time.")); 897 - return -ENOTSUP; 898 - } 899 - 900 - int parse_events_load_bpf(struct parse_events_state *parse_state, 901 - struct list_head *list __maybe_unused, 902 - char *bpf_file_name __maybe_unused, 903 - bool source __maybe_unused, 904 - struct list_head *head_config __maybe_unused, 905 - void *loc_) 906 - { 907 - YYLTYPE *loc = loc_; 908 - 909 - parse_events_error__handle(parse_state->error, loc->first_column, 910 - strdup("BPF support is not compiled"), 911 - strdup("Make sure libbpf-devel is available at build time.")); 912 - return -ENOTSUP; 913 - } 914 - #endif // HAVE_LIBBPF_SUPPORT 915 650 916 651 static int 917 652 parse_breakpoint_type(const char *type, struct perf_event_attr *attr) ··· 2007 2274 .list = LIST_HEAD_INIT(parse_state.list), 2008 2275 .idx = evlist->core.nr_entries, 2009 2276 .error = err, 2010 - .evlist = evlist, 2011 2277 .stoken = PE_START_EVENTS, 2012 2278 .fake_pmu = fake_pmu, 2013 2279 .pmu_filter = pmu_filter,
-15
tools/perf/util/parse-events.h
··· 118 118 int idx; 119 119 /* Error information. */ 120 120 struct parse_events_error *error; 121 - /* Used by BPF event creation. */ 122 - struct evlist *evlist; 123 121 /* Holds returned terms for term parsing. */ 124 122 struct list_head *terms; 125 123 /* Start token. */ ··· 158 160 const char *sys, const char *event, 159 161 struct parse_events_error *error, 160 162 struct list_head *head_config, void *loc); 161 - int parse_events_load_bpf(struct parse_events_state *parse_state, 162 - struct list_head *list, 163 - char *bpf_file_name, 164 - bool source, 165 - struct list_head *head_config, 166 - void *loc); 167 - /* Provide this function for perf test */ 168 - struct bpf_object; 169 - int parse_events_load_bpf_obj(struct parse_events_state *parse_state, 170 - struct list_head *list, 171 - struct bpf_object *obj, 172 - struct list_head *head_config, 173 - void *loc); 174 163 int parse_events_add_numeric(struct parse_events_state *parse_state, 175 164 struct list_head *list, 176 165 u32 type, u64 config,
-31
tools/perf/util/parse-events.l
··· 68 68 return str(scanner, state->match_legacy_cache_terms ? PE_LEGACY_CACHE : PE_NAME); 69 69 } 70 70 71 - static bool isbpf_suffix(char *text) 72 - { 73 - int len = strlen(text); 74 - 75 - if (len < 2) 76 - return false; 77 - if ((text[len - 1] == 'c' || text[len - 1] == 'o') && 78 - text[len - 2] == '.') 79 - return true; 80 - if (len > 4 && !strcmp(text + len - 4, ".obj")) 81 - return true; 82 - return false; 83 - } 84 - 85 - static bool isbpf(yyscan_t scanner) 86 - { 87 - char *text = parse_events_get_text(scanner); 88 - struct stat st; 89 - 90 - if (!isbpf_suffix(text)) 91 - return false; 92 - 93 - return stat(text, &st) == 0; 94 - } 95 - 96 71 /* 97 72 * This function is called when the parser gets two kind of input: 98 73 * ··· 154 179 group [^,{}/]*[{][^}]*[}][^,{}/]* 155 180 event_pmu [^,{}/]+[/][^/]*[/][^,{}/]* 156 181 event [^,{}/]+ 157 - bpf_object [^,{}]+\.(o|bpf)[a-zA-Z0-9._]* 158 - bpf_source [^,{}]+\.c[a-zA-Z0-9._]* 159 182 160 183 num_dec [0-9]+ 161 184 num_hex 0x[a-fA-F0-9]+ ··· 206 233 } 207 234 208 235 {event_pmu} | 209 - {bpf_object} | 210 - {bpf_source} | 211 236 {event} { 212 237 BEGIN(INITIAL); 213 238 REWIND(1); ··· 334 363 {num_hex} { return value(yyscanner, 16); } 335 364 336 365 {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } 337 - {bpf_object} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_OBJECT); } 338 - {bpf_source} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_SOURCE); } 339 366 {name} { return str(yyscanner, PE_NAME); } 340 367 {name_tag} { return str(yyscanner, PE_NAME); } 341 368 "/" { BEGIN(config); return '/'; }
+1 -43
tools/perf/util/parse-events.y
··· 60 60 %token PE_VALUE_SYM_TOOL 61 61 %token PE_EVENT_NAME 62 62 %token PE_RAW PE_NAME 63 - %token PE_BPF_OBJECT PE_BPF_SOURCE 64 63 %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH 65 64 %token PE_LEGACY_CACHE 66 65 %token PE_PREFIX_MEM ··· 74 75 %type <num> value_sym 75 76 %type <str> PE_RAW 76 77 %type <str> PE_NAME 77 - %type <str> PE_BPF_OBJECT 78 - %type <str> PE_BPF_SOURCE 79 78 %type <str> PE_LEGACY_CACHE 80 79 %type <str> PE_MODIFIER_EVENT 81 80 %type <str> PE_MODIFIER_BP ··· 94 97 %type <list_evsel> event_legacy_tracepoint 95 98 %type <list_evsel> event_legacy_numeric 96 99 %type <list_evsel> event_legacy_raw 97 - %type <list_evsel> event_bpf_file 98 100 %type <list_evsel> event_def 99 101 %type <list_evsel> event_mod 100 102 %type <list_evsel> event_name ··· 267 271 event_legacy_mem sep_dc | 268 272 event_legacy_tracepoint sep_dc | 269 273 event_legacy_numeric sep_dc | 270 - event_legacy_raw sep_dc | 271 - event_bpf_file 274 + event_legacy_raw sep_dc 272 275 273 276 event_pmu: 274 277 PE_NAME opt_pmu_config ··· 607 612 free($1); 608 613 err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2, 609 614 /*wildcard=*/false); 610 - parse_events_terms__delete($2); 611 - if (err) { 612 - free(list); 613 - PE_ABORT(err); 614 - } 615 - $$ = list; 616 - } 617 - 618 - event_bpf_file: 619 - PE_BPF_OBJECT opt_event_config 620 - { 621 - struct parse_events_state *parse_state = _parse_state; 622 - struct list_head *list; 623 - int err; 624 - 625 - list = alloc_list(); 626 - if (!list) 627 - YYNOMEM; 628 - err = parse_events_load_bpf(parse_state, list, $1, false, $2, &@1); 629 - parse_events_terms__delete($2); 630 - free($1); 631 - if (err) { 632 - free(list); 633 - PE_ABORT(err); 634 - } 635 - $$ = list; 636 - } 637 - | 638 - PE_BPF_SOURCE opt_event_config 639 - { 640 - struct list_head *list; 641 - int err; 642 - 643 - list = alloc_list(); 644 - if (!list) 645 - YYNOMEM; 646 - err = parse_events_load_bpf(_parse_state, list, $1, true, $2, &@1); 647 615 parse_events_terms__delete($2); 648 616 if (err) { 649 617 free(list);