* [PATCH bpf-next 0/4] selftests/bpf: Fix a couple of test failures with LTO kernel
@ 2024-03-02 16:50 Yonghong Song
2024-03-02 16:50 ` [PATCH bpf-next 1/4] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test Yonghong Song
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Yonghong Song @ 2024-03-02 16:50 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team,
Martin KaFai Lau
With a LTO kernel built with clang, I encountered two test failures,
ksyms and kprobe_multi_bench_attach/kernel. Both test failures are
due to static variable/function renaming due to cross-file inlining.
The solution is to either skip the test or filter out those renamed
functions. A helper function check_lto_kernel() is introduced to
identify whether the underlying kernel is built with LTO or not.
Please see each individual patches for details.
Yonghong Song (4):
selftests/bpf: Replace CHECK with ASSERT macros for ksyms test
selftests/bpf: Add check_lto_kernel() helper
selftests/bpf: Fix possible ksyms test failure with LTO kernel
selftests/bpf: Fix possible kprobe_multi_bench_attach test failure
with LTO kernel
.../bpf/prog_tests/kprobe_multi_test.c | 7 +++
.../testing/selftests/bpf/prog_tests/ksyms.c | 42 +++++++++--------
tools/testing/selftests/bpf/testing_helpers.c | 47 +++++++++++++++++++
tools/testing/selftests/bpf/testing_helpers.h | 1 +
4 files changed, 78 insertions(+), 19 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH bpf-next 1/4] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test 2024-03-02 16:50 [PATCH bpf-next 0/4] selftests/bpf: Fix a couple of test failures with LTO kernel Yonghong Song @ 2024-03-02 16:50 ` Yonghong Song 2024-03-05 0:17 ` Andrii Nakryiko 2024-03-02 16:50 ` [PATCH bpf-next 2/4] selftests/bpf: Add check_lto_kernel() helper Yonghong Song ` (2 subsequent siblings) 3 siblings, 1 reply; 9+ messages in thread From: Yonghong Song @ 2024-03-02 16:50 UTC (permalink / raw) To: bpf Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team, Martin KaFai Lau I am going to modify ksyms test later so take this opportunity to replace old CHECK macros with new ASSERT macros. No functionality change. Signed-off-by: Yonghong Song <yonghong.song@linux.dev> --- .../testing/selftests/bpf/prog_tests/ksyms.c | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c index b295969b263b..e081f8bf3f17 100644 --- a/tools/testing/selftests/bpf/prog_tests/ksyms.c +++ b/tools/testing/selftests/bpf/prog_tests/ksyms.c @@ -5,8 +5,6 @@ #include "test_ksyms.skel.h" #include <sys/stat.h> -static int duration; - void test_ksyms(void) { const char *btf_path = "/sys/kernel/btf/vmlinux"; @@ -18,43 +16,45 @@ void test_ksyms(void) int err; err = kallsyms_find("bpf_link_fops", &link_fops_addr); - if (CHECK(err == -EINVAL, "kallsyms_fopen", "failed to open: %d\n", errno)) + if (err == -EINVAL) { + ASSERT_TRUE(false, "kallsyms_fopen for bpf_link_fops"); return; - if (CHECK(err == -ENOENT, "ksym_find", "symbol 'bpf_link_fops' not found\n")) + } + if (err == -ENOENT) { + ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); return; + } err = kallsyms_find("__per_cpu_start", &per_cpu_start_addr); - if (CHECK(err == -EINVAL, "kallsyms_fopen", "failed to open: %d\n", errno)) + if (err == -EINVAL) { + ASSERT_TRUE(false, "kallsyms_fopen for __per_cpu_start"); return; - if (CHECK(err == -ENOENT, "ksym_find", "symbol 'per_cpu_start' not found\n")) + } + if (err == -ENOENT) { + ASSERT_TRUE(false, "ksym_find for __per_cpu_start"); return; + } - if (CHECK(stat(btf_path, &st), "stat_btf", "err %d\n", errno)) + if (!ASSERT_OK(stat(btf_path, &st), "stat_btf")) return; btf_size = st.st_size; skel = test_ksyms__open_and_load(); - if (CHECK(!skel, "skel_open", "failed to open and load skeleton\n")) + if (!ASSERT_OK_PTR(skel, "test_ksyms__open_and_load")) return; err = test_ksyms__attach(skel); - if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) + if (!ASSERT_OK(err, "test_ksyms__attach")) goto cleanup; /* trigger tracepoint */ usleep(1); data = skel->data; - CHECK(data->out__bpf_link_fops != link_fops_addr, "bpf_link_fops", - "got 0x%llx, exp 0x%llx\n", - data->out__bpf_link_fops, link_fops_addr); - CHECK(data->out__bpf_link_fops1 != 0, "bpf_link_fops1", - "got %llu, exp %llu\n", data->out__bpf_link_fops1, (__u64)0); - CHECK(data->out__btf_size != btf_size, "btf_size", - "got %llu, exp %llu\n", data->out__btf_size, btf_size); - CHECK(data->out__per_cpu_start != per_cpu_start_addr, "__per_cpu_start", - "got %llu, exp %llu\n", data->out__per_cpu_start, - per_cpu_start_addr); + ASSERT_EQ(data->out__bpf_link_fops, link_fops_addr, "bpf_link_fops"); + ASSERT_EQ(data->out__bpf_link_fops1, 0, "bpf_link_fops1"); + ASSERT_EQ(data->out__btf_size, btf_size, "btf_size"); + ASSERT_EQ(data->out__per_cpu_start, per_cpu_start_addr, "__per_cpu_start"); cleanup: test_ksyms__destroy(skel); -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next 1/4] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test 2024-03-02 16:50 ` [PATCH bpf-next 1/4] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test Yonghong Song @ 2024-03-05 0:17 ` Andrii Nakryiko 2024-03-05 7:21 ` Yonghong Song 0 siblings, 1 reply; 9+ messages in thread From: Andrii Nakryiko @ 2024-03-05 0:17 UTC (permalink / raw) To: Yonghong Song Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team, Martin KaFai Lau On Sat, Mar 2, 2024 at 8:50 AM Yonghong Song <yonghong.song@linux.dev> wrote: > > I am going to modify ksyms test later so take this opportunity > to replace old CHECK macros with new ASSERT macros. > No functionality change. > > Signed-off-by: Yonghong Song <yonghong.song@linux.dev> > --- > .../testing/selftests/bpf/prog_tests/ksyms.c | 38 +++++++++---------- > 1 file changed, 19 insertions(+), 19 deletions(-) > > diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c > index b295969b263b..e081f8bf3f17 100644 > --- a/tools/testing/selftests/bpf/prog_tests/ksyms.c > +++ b/tools/testing/selftests/bpf/prog_tests/ksyms.c > @@ -5,8 +5,6 @@ > #include "test_ksyms.skel.h" > #include <sys/stat.h> > > -static int duration; > - > void test_ksyms(void) > { > const char *btf_path = "/sys/kernel/btf/vmlinux"; > @@ -18,43 +16,45 @@ void test_ksyms(void) > int err; > > err = kallsyms_find("bpf_link_fops", &link_fops_addr); > - if (CHECK(err == -EINVAL, "kallsyms_fopen", "failed to open: %d\n", errno)) > + if (err == -EINVAL) { > + ASSERT_TRUE(false, "kallsyms_fopen for bpf_link_fops"); should this (and few other cases below) be ASSERT_EQ()/ASSERT_NEQ() (whichever makes sense, I can't reason about CHECK() conditions). ASSERT_TRUE(false) is a last resort way, we have more meaningful checks. > return; > - if (CHECK(err == -ENOENT, "ksym_find", "symbol 'bpf_link_fops' not found\n")) > + } > + if (err == -ENOENT) { > + ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); > return; > + } > > err = kallsyms_find("__per_cpu_start", &per_cpu_start_addr); > - if (CHECK(err == -EINVAL, "kallsyms_fopen", "failed to open: %d\n", errno)) > + if (err == -EINVAL) { > + ASSERT_TRUE(false, "kallsyms_fopen for __per_cpu_start"); > return; > - if (CHECK(err == -ENOENT, "ksym_find", "symbol 'per_cpu_start' not found\n")) > + } > + if (err == -ENOENT) { > + ASSERT_TRUE(false, "ksym_find for __per_cpu_start"); > return; > + } > > - if (CHECK(stat(btf_path, &st), "stat_btf", "err %d\n", errno)) > + if (!ASSERT_OK(stat(btf_path, &st), "stat_btf")) > return; > btf_size = st.st_size; > > skel = test_ksyms__open_and_load(); > - if (CHECK(!skel, "skel_open", "failed to open and load skeleton\n")) > + if (!ASSERT_OK_PTR(skel, "test_ksyms__open_and_load")) > return; > > err = test_ksyms__attach(skel); > - if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) > + if (!ASSERT_OK(err, "test_ksyms__attach")) > goto cleanup; > > /* trigger tracepoint */ > usleep(1); > > data = skel->data; > - CHECK(data->out__bpf_link_fops != link_fops_addr, "bpf_link_fops", > - "got 0x%llx, exp 0x%llx\n", > - data->out__bpf_link_fops, link_fops_addr); > - CHECK(data->out__bpf_link_fops1 != 0, "bpf_link_fops1", > - "got %llu, exp %llu\n", data->out__bpf_link_fops1, (__u64)0); > - CHECK(data->out__btf_size != btf_size, "btf_size", > - "got %llu, exp %llu\n", data->out__btf_size, btf_size); > - CHECK(data->out__per_cpu_start != per_cpu_start_addr, "__per_cpu_start", > - "got %llu, exp %llu\n", data->out__per_cpu_start, > - per_cpu_start_addr); > + ASSERT_EQ(data->out__bpf_link_fops, link_fops_addr, "bpf_link_fops"); > + ASSERT_EQ(data->out__bpf_link_fops1, 0, "bpf_link_fops1"); > + ASSERT_EQ(data->out__btf_size, btf_size, "btf_size"); > + ASSERT_EQ(data->out__per_cpu_start, per_cpu_start_addr, "__per_cpu_start"); > > cleanup: > test_ksyms__destroy(skel); > -- > 2.43.0 > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next 1/4] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test 2024-03-05 0:17 ` Andrii Nakryiko @ 2024-03-05 7:21 ` Yonghong Song 0 siblings, 0 replies; 9+ messages in thread From: Yonghong Song @ 2024-03-05 7:21 UTC (permalink / raw) To: Andrii Nakryiko Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team, Martin KaFai Lau On 3/4/24 4:17 PM, Andrii Nakryiko wrote: > On Sat, Mar 2, 2024 at 8:50 AM Yonghong Song <yonghong.song@linux.dev> wrote: >> I am going to modify ksyms test later so take this opportunity >> to replace old CHECK macros with new ASSERT macros. >> No functionality change. >> >> Signed-off-by: Yonghong Song <yonghong.song@linux.dev> >> --- >> .../testing/selftests/bpf/prog_tests/ksyms.c | 38 +++++++++---------- >> 1 file changed, 19 insertions(+), 19 deletions(-) >> >> diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c >> index b295969b263b..e081f8bf3f17 100644 >> --- a/tools/testing/selftests/bpf/prog_tests/ksyms.c >> +++ b/tools/testing/selftests/bpf/prog_tests/ksyms.c >> @@ -5,8 +5,6 @@ >> #include "test_ksyms.skel.h" >> #include <sys/stat.h> >> >> -static int duration; >> - >> void test_ksyms(void) >> { >> const char *btf_path = "/sys/kernel/btf/vmlinux"; >> @@ -18,43 +16,45 @@ void test_ksyms(void) >> int err; >> >> err = kallsyms_find("bpf_link_fops", &link_fops_addr); >> - if (CHECK(err == -EINVAL, "kallsyms_fopen", "failed to open: %d\n", errno)) >> + if (err == -EINVAL) { >> + ASSERT_TRUE(false, "kallsyms_fopen for bpf_link_fops"); > should this (and few other cases below) be ASSERT_EQ()/ASSERT_NEQ() > (whichever makes sense, I can't reason about CHECK() conditions). The below 'err == -ENOENT' case will later be modified in Patch 3 where I cannot do ASSERT_EQ(err, -ENOENT) which is why I do 'err == -EINVAL' here. But you have a good point that ASSERT_EQ/NEQ is easier to understand. Will fix it in the next revision. > > ASSERT_TRUE(false) is a last resort way, we have more meaningful checks. > >> return; >> - if (CHECK(err == -ENOENT, "ksym_find", "symbol 'bpf_link_fops' not found\n")) >> + } >> + if (err == -ENOENT) { >> + ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); >> return; >> + } >> >> err = kallsyms_find("__per_cpu_start", &per_cpu_start_addr); >> - if (CHECK(err == -EINVAL, "kallsyms_fopen", "failed to open: %d\n", errno)) >> + if (err == -EINVAL) { >> + ASSERT_TRUE(false, "kallsyms_fopen for __per_cpu_start"); >> return; >> - if (CHECK(err == -ENOENT, "ksym_find", "symbol 'per_cpu_start' not found\n")) >> + } >> + if (err == -ENOENT) { >> + ASSERT_TRUE(false, "ksym_find for __per_cpu_start"); >> return; >> + } [...] ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH bpf-next 2/4] selftests/bpf: Add check_lto_kernel() helper 2024-03-02 16:50 [PATCH bpf-next 0/4] selftests/bpf: Fix a couple of test failures with LTO kernel Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 1/4] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test Yonghong Song @ 2024-03-02 16:50 ` Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 3/4] selftests/bpf: Fix possible ksyms test failure with LTO kernel Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 4/4] selftests/bpf: Fix possible kprobe_multi_bench_attach " Yonghong Song 3 siblings, 0 replies; 9+ messages in thread From: Yonghong Song @ 2024-03-02 16:50 UTC (permalink / raw) To: bpf Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team, Martin KaFai Lau Add check_lto_kernel() helper to detect whether the underlying kernel enabled CONFIG_LTO or not. The function check_lto_kernel() can be used by selftests to handle some lto-specific situations. The code is heavily borrowed from libbpf function bpf_object__read_kconfig_file(). Signed-off-by: Yonghong Song <yonghong.song@linux.dev> --- tools/testing/selftests/bpf/testing_helpers.c | 47 +++++++++++++++++++ tools/testing/selftests/bpf/testing_helpers.h | 1 + 2 files changed, 48 insertions(+) diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c index 28b6646662af..3f74f73843cf 100644 --- a/tools/testing/selftests/bpf/testing_helpers.c +++ b/tools/testing/selftests/bpf/testing_helpers.c @@ -5,6 +5,8 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#include <zlib.h> +#include <sys/utsname.h> #include <bpf/bpf.h> #include <bpf/libbpf.h> #include "test_progs.h" @@ -475,3 +477,48 @@ bool is_jit_enabled(void) return enabled; } + +int check_lto_kernel(void) +{ + static int check_lto = 2; + char buf[PATH_MAX]; + struct utsname uts; + gzFile file; + int len; + + if (check_lto != 2) + return check_lto; + + uname(&uts); + len = snprintf(buf, PATH_MAX, "/boot/config-%s", uts.release); + if (len < 0) { + check_lto = -EINVAL; + goto out; + } else if (len >= PATH_MAX) { + check_lto = -ENAMETOOLONG; + goto out; + } + + /* gzopen also accepts uncompressed files. */ + file = gzopen(buf, "re"); + if (!file) + file = gzopen("/proc/config.gz", "re"); + + if (!file) { + check_lto = -ENOENT; + goto out; + } + + check_lto = 0; + while (gzgets(file, buf, sizeof(buf))) { + /* buf also contains '\n', skip it during comparison. */ + if (!strncmp(buf, "CONFIG_LTO=y", 12)) { + check_lto = 1; + break; + } + } + + gzclose(file); +out: + return check_lto; +} diff --git a/tools/testing/selftests/bpf/testing_helpers.h b/tools/testing/selftests/bpf/testing_helpers.h index d55f6ab12433..57683b3a1280 100644 --- a/tools/testing/selftests/bpf/testing_helpers.h +++ b/tools/testing/selftests/bpf/testing_helpers.h @@ -55,5 +55,6 @@ struct bpf_insn; int get_xlated_program(int fd_prog, struct bpf_insn **buf, __u32 *cnt); int testing_prog_flags(void); bool is_jit_enabled(void); +int check_lto_kernel(void); #endif /* __TESTING_HELPERS_H */ -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH bpf-next 3/4] selftests/bpf: Fix possible ksyms test failure with LTO kernel 2024-03-02 16:50 [PATCH bpf-next 0/4] selftests/bpf: Fix a couple of test failures with LTO kernel Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 1/4] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 2/4] selftests/bpf: Add check_lto_kernel() helper Yonghong Song @ 2024-03-02 16:50 ` Yonghong Song 2024-03-05 5:37 ` Alexei Starovoitov 2024-03-02 16:50 ` [PATCH bpf-next 4/4] selftests/bpf: Fix possible kprobe_multi_bench_attach " Yonghong Song 3 siblings, 1 reply; 9+ messages in thread From: Yonghong Song @ 2024-03-02 16:50 UTC (permalink / raw) To: bpf Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team, Martin KaFai Lau In my locally build clang LTO kernel (enabling CONFIG_LTO and CONFIG_LTO_CLANG_THIN), ksyms test failed like: test_ksyms:PASS:kallsyms_fopen 0 nsec test_ksyms:FAIL:ksym_find symbol 'bpf_link_fops' not found #118 ksyms:FAIL The reason is that 'bpf_link_fops' is renamed to bpf_link_fops.llvm.8325593422554671469 Due to cross-file inlining, the static variable 'bpf_link_fops' in syscall.c is used by a function in another file. To avoid potential duplicated names, the llvm added suffix '.llvm.<hash>'. To fix the failure, we can skip this test with LTO kernel if the symbol 'bpf_link_fops' is not found in kallsyms. After this patch, with the same LTO kernel: #118 ksyms:SKIP Signed-off-by: Yonghong Song <yonghong.song@linux.dev> --- tools/testing/selftests/bpf/prog_tests/ksyms.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c index e081f8bf3f17..cd81f190c5d7 100644 --- a/tools/testing/selftests/bpf/prog_tests/ksyms.c +++ b/tools/testing/selftests/bpf/prog_tests/ksyms.c @@ -21,7 +21,11 @@ void test_ksyms(void) return; } if (err == -ENOENT) { - ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); + /* bpf_link_fops might be renamed to bpf_link_fops.llvm.<hash> in LTO kernel. */ + if (check_lto_kernel() == 1) + test__skip(); + else + ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); return; } -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next 3/4] selftests/bpf: Fix possible ksyms test failure with LTO kernel 2024-03-02 16:50 ` [PATCH bpf-next 3/4] selftests/bpf: Fix possible ksyms test failure with LTO kernel Yonghong Song @ 2024-03-05 5:37 ` Alexei Starovoitov 2024-03-05 7:24 ` Yonghong Song 0 siblings, 1 reply; 9+ messages in thread From: Alexei Starovoitov @ 2024-03-05 5:37 UTC (permalink / raw) To: Yonghong Song Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Kernel Team, Martin KaFai Lau On Sat, Mar 2, 2024 at 8:50 AM Yonghong Song <yonghong.song@linux.dev> wrote: > > In my locally build clang LTO kernel (enabling CONFIG_LTO and > CONFIG_LTO_CLANG_THIN), ksyms test failed like: > test_ksyms:PASS:kallsyms_fopen 0 nsec > test_ksyms:FAIL:ksym_find symbol 'bpf_link_fops' not found > #118 ksyms:FAIL > > The reason is that 'bpf_link_fops' is renamed to > bpf_link_fops.llvm.8325593422554671469 > Due to cross-file inlining, the static variable 'bpf_link_fops' > in syscall.c is used by a function in another file. To avoid > potential duplicated names, the llvm added suffix '.llvm.<hash>'. > > To fix the failure, we can skip this test with LTO kernel > if the symbol 'bpf_link_fops' is not found in kallsyms. > > After this patch, with the same LTO kernel: > #118 ksyms:SKIP > > Signed-off-by: Yonghong Song <yonghong.song@linux.dev> > --- > tools/testing/selftests/bpf/prog_tests/ksyms.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c > index e081f8bf3f17..cd81f190c5d7 100644 > --- a/tools/testing/selftests/bpf/prog_tests/ksyms.c > +++ b/tools/testing/selftests/bpf/prog_tests/ksyms.c > @@ -21,7 +21,11 @@ void test_ksyms(void) > return; > } > if (err == -ENOENT) { > - ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); > + /* bpf_link_fops might be renamed to bpf_link_fops.llvm.<hash> in LTO kernel. */ > + if (check_lto_kernel() == 1) > + test__skip(); > + else > + ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); I'm afraid LTO breakage is bigger than this. pid_iter program as part of bpftool is using bpf_link_fops too. I suspect that part of bpftool feature is broken on LTO kernel. We need to find a solution instead of 'skip' a selftest. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next 3/4] selftests/bpf: Fix possible ksyms test failure with LTO kernel 2024-03-05 5:37 ` Alexei Starovoitov @ 2024-03-05 7:24 ` Yonghong Song 0 siblings, 0 replies; 9+ messages in thread From: Yonghong Song @ 2024-03-05 7:24 UTC (permalink / raw) To: Alexei Starovoitov Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Kernel Team, Martin KaFai Lau On 3/4/24 9:37 PM, Alexei Starovoitov wrote: > On Sat, Mar 2, 2024 at 8:50 AM Yonghong Song <yonghong.song@linux.dev> wrote: >> In my locally build clang LTO kernel (enabling CONFIG_LTO and >> CONFIG_LTO_CLANG_THIN), ksyms test failed like: >> test_ksyms:PASS:kallsyms_fopen 0 nsec >> test_ksyms:FAIL:ksym_find symbol 'bpf_link_fops' not found >> #118 ksyms:FAIL >> >> The reason is that 'bpf_link_fops' is renamed to >> bpf_link_fops.llvm.8325593422554671469 >> Due to cross-file inlining, the static variable 'bpf_link_fops' >> in syscall.c is used by a function in another file. To avoid >> potential duplicated names, the llvm added suffix '.llvm.<hash>'. >> >> To fix the failure, we can skip this test with LTO kernel >> if the symbol 'bpf_link_fops' is not found in kallsyms. >> >> After this patch, with the same LTO kernel: >> #118 ksyms:SKIP >> >> Signed-off-by: Yonghong Song <yonghong.song@linux.dev> >> --- >> tools/testing/selftests/bpf/prog_tests/ksyms.c | 6 +++++- >> 1 file changed, 5 insertions(+), 1 deletion(-) >> >> diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c >> index e081f8bf3f17..cd81f190c5d7 100644 >> --- a/tools/testing/selftests/bpf/prog_tests/ksyms.c >> +++ b/tools/testing/selftests/bpf/prog_tests/ksyms.c >> @@ -21,7 +21,11 @@ void test_ksyms(void) >> return; >> } >> if (err == -ENOENT) { >> - ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); >> + /* bpf_link_fops might be renamed to bpf_link_fops.llvm.<hash> in LTO kernel. */ >> + if (check_lto_kernel() == 1) >> + test__skip(); >> + else >> + ASSERT_TRUE(false, "ksym_find for bpf_link_fops"); > I'm afraid LTO breakage is bigger than this. > pid_iter program as part of bpftool is using bpf_link_fops too. > I suspect that part of bpftool feature is broken on LTO kernel. > We need to find a solution instead of 'skip' a selftest. Thanks for pointing this out! Let me do some investigation on how to resolve this. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH bpf-next 4/4] selftests/bpf: Fix possible kprobe_multi_bench_attach test failure with LTO kernel 2024-03-02 16:50 [PATCH bpf-next 0/4] selftests/bpf: Fix a couple of test failures with LTO kernel Yonghong Song ` (2 preceding siblings ...) 2024-03-02 16:50 ` [PATCH bpf-next 3/4] selftests/bpf: Fix possible ksyms test failure with LTO kernel Yonghong Song @ 2024-03-02 16:50 ` Yonghong Song 3 siblings, 0 replies; 9+ messages in thread From: Yonghong Song @ 2024-03-02 16:50 UTC (permalink / raw) To: bpf Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, kernel-team, Martin KaFai Lau In my locally build clang LTO kernel (enabling CONFIG_LTO and CONFIG_LTO_CLANG_THIN), kprobe_multi_bench_attach/kernel subtest failed like: test_kprobe_multi_bench_attach:PASS:get_syms 0 nsec test_kprobe_multi_bench_attach:PASS:kprobe_multi_empty__open_and_load 0 nsec libbpf: prog 'test_kprobe_empty': failed to attach: No such process test_kprobe_multi_bench_attach:FAIL:bpf_program__attach_kprobe_multi_opts unexpected error: -3 #114/1 kprobe_multi_bench_attach/kernel:FAIL There are multiple symbols in /sys/kernel/debug/tracing/available_filter_functions are renamed in kallsyms due to cross file inlining. One example is for static function __access_remote_vm in mm/memory.c. In a non-LTO kernel, we have the following call stack: ptrace_access_vm (global, kernel/ptrace.c) access_remote_vm (global, mm/memory.c) __access_remote_vm (static, mm/memory.c) With LTO kernel, it is possible that access_remote_vm() is inlined by ptrace_access_vm(). So we end up with the following call stack: ptrace_access_vm (global, kernel/ptrace.c) __access_remote_vm (static, mm/memory.c) The compiler renames __access_remote_vm to __access_remote_vm.llvm.<hash> to prevent potential name collision. This patch removed __access_remote_vm and other similar functions from kprobe_multi_attach by checking if the symbol like __access_remote_vm does not exist in kallsyms with LTO kernel. The test succeeded after this change: #114/1 kprobe_multi_bench_attach/kernel:OK Signed-off-by: Yonghong Song <yonghong.song@linux.dev> --- tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c index 05000810e28e..2aad5f9cdb84 100644 --- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c +++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c @@ -341,10 +341,15 @@ static int get_syms(char ***symsp, size_t *cntp, bool kernel) size_t cap = 0, cnt = 0, i; char *name = NULL, **syms = NULL; struct hashmap *map; + bool lto_kernel; char buf[256]; FILE *f; int err = 0; + lto_kernel = kernel && check_lto_kernel() == 1; + if (lto_kernel && !ASSERT_OK(load_kallsyms(), "load_kallsyms")) + return -EINVAL; + /* * The available_filter_functions contains many duplicates, * but other than that all symbols are usable in kprobe multi @@ -393,6 +398,8 @@ static int get_syms(char ***symsp, size_t *cntp, bool kernel) if (!strncmp(name, "__ftrace_invalid_address__", sizeof("__ftrace_invalid_address__") - 1)) continue; + if (lto_kernel && ksym_get_addr(name) == 0) + continue; err = hashmap__add(map, name, 0); if (err == -EEXIST) { -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-03-05 7:24 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-03-02 16:50 [PATCH bpf-next 0/4] selftests/bpf: Fix a couple of test failures with LTO kernel Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 1/4] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test Yonghong Song 2024-03-05 0:17 ` Andrii Nakryiko 2024-03-05 7:21 ` Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 2/4] selftests/bpf: Add check_lto_kernel() helper Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 3/4] selftests/bpf: Fix possible ksyms test failure with LTO kernel Yonghong Song 2024-03-05 5:37 ` Alexei Starovoitov 2024-03-05 7:24 ` Yonghong Song 2024-03-02 16:50 ` [PATCH bpf-next 4/4] selftests/bpf: Fix possible kprobe_multi_bench_attach " Yonghong Song
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox