From patchwork Thu Mar 21 20:01:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yonghong Song X-Patchwork-Id: 13599324 X-Patchwork-Delegate: bpf@iogearbox.net Received: from 66-220-155-178.mail-mxout.facebook.com (66-220-155-178.mail-mxout.facebook.com [66.220.155.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66EA5134422 for ; Thu, 21 Mar 2024 20:01:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.155.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051277; cv=none; b=MWaSL12q3H3wDUGaT+9egqyvEkdr5kdIRjPPHU1ZwDeC1TrYXEebvLhDOykWKlyYeNmCMwbJLbcG9Sx0Dl+9nl3kRBA9yDVnzzoDBkB0hwhEJU8rwwdu8NC07R0+gEBG7zEX4oP11GEuzOivE1KbFz/oONbyyFg877gpMqzEkIA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051277; c=relaxed/simple; bh=pVCZfxf6U9+W68kjZBGR/lhrpUzP7llV8BmA0l6RObs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jk9hBD086UcJkx20wr2FaekseakECfaL0NhZg4W7wtxgLkEswzoodhzZxMsE2KiVqFpEeD+xAmuBfJn16VQrgtS2JQ0bz6iXDaCpPmeyw+GMEDReSttKnrI03zHCob/Ry2LgTMFSO6sm1vrj3ZvlON1A7gMYTbiWrsN0JHZJ/Nc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev; spf=fail smtp.mailfrom=linux.dev; arc=none smtp.client-ip=66.220.155.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=linux.dev Received: by devbig309.ftw3.facebook.com (Postfix, from userid 128203) id D25A62219025; Thu, 21 Mar 2024 13:01:03 -0700 (PDT) From: Yonghong Song To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , kernel-team@fb.com, Martin KaFai Lau Subject: [PATCH bpf-next v2 1/5] selftests/bpf: Replace CHECK with ASSERT macros for ksyms test Date: Thu, 21 Mar 2024 13:01:03 -0700 Message-ID: <20240321200103.2218888-1-yonghong.song@linux.dev> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240321200058.2218328-1-yonghong.song@linux.dev> References: <20240321200058.2218328-1-yonghong.song@linux.dev> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net 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 Acked-by: Jiri Olsa --- .../testing/selftests/bpf/prog_tests/ksyms.c | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c index b295969b263b..6a86d1f07800 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 -static int duration; - void test_ksyms(void) { const char *btf_path = "/sys/kernel/btf/vmlinux"; @@ -18,43 +16,33 @@ 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)) - return; - if (CHECK(err == -ENOENT, "ksym_find", "symbol 'bpf_link_fops' not found\n")) + if (!ASSERT_TRUE(err != -EINVAL && err != -ENOENT, "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)) - return; - if (CHECK(err == -ENOENT, "ksym_find", "symbol 'per_cpu_start' not found\n")) + if (!ASSERT_TRUE(err != -EINVAL && err != -ENOENT, "__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); From patchwork Thu Mar 21 20:01:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yonghong Song X-Patchwork-Id: 13599325 X-Patchwork-Delegate: bpf@iogearbox.net Received: from 66-220-155-178.mail-mxout.facebook.com (66-220-155-178.mail-mxout.facebook.com [66.220.155.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66EEA134428 for ; Thu, 21 Mar 2024 20:01:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.155.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051277; cv=none; b=oJ3HVDj+EgAcA5HC3jvnyL99gwX10n6WqxhHMl9fcb/GA7qvWQmJ+D3+15DGJkcvowMlx2mj3aNNKFIwEvs+kZy9syU+pfDYksMBEjPh8sTYXTvrkne9JOFMFyoceeO2voiVEfNkwjX4uD2cts3C+mlIAP3j1Nn63lBa38oswXI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051277; c=relaxed/simple; bh=+XzNW0r9gGhfWDAgjiQ5xYNIkosQ3qBe4Uk/6UbFQ7w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OeGCEYQbvFVK7yaDMCuWql5TFuNoWda0apVVdLmxYSe8mPZv8zpOGMmYeKhfVmKVcVsCsbOefa28rGwv1xMmiN0ptgqMJRwBFJ7+2dA1kPqdsUks0KDYSVLPxyRCyLuHiIokyGaiiWejlEAQj1NVWxitNelL6KToFmnaf5zRRIU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev; spf=fail smtp.mailfrom=linux.dev; arc=none smtp.client-ip=66.220.155.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=linux.dev Received: by devbig309.ftw3.facebook.com (Postfix, from userid 128203) id EB8CB221903A; Thu, 21 Mar 2024 13:01:08 -0700 (PDT) From: Yonghong Song To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , kernel-team@fb.com, Martin KaFai Lau Subject: [PATCH bpf-next v2 2/5] libbpf: Mark libbpf_kallsyms_parse static function Date: Thu, 21 Mar 2024 13:01:08 -0700 Message-ID: <20240321200108.2219280-1-yonghong.song@linux.dev> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240321200058.2218328-1-yonghong.song@linux.dev> References: <20240321200058.2218328-1-yonghong.song@linux.dev> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Currently libbpf_kallsyms_parse() function is declared as a global function but actually it is not a API and there is no external users in bpftool/bpf-selftests. So let us mark the function as static. Signed-off-by: Yonghong Song --- tools/lib/bpf/libbpf.c | 2 +- tools/lib/bpf/libbpf_internal.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 86df0d50cba7..a7a89269148c 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -7982,7 +7982,7 @@ static int bpf_object__sanitize_maps(struct bpf_object *obj) return 0; } -int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *ctx) +static int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *ctx) { char sym_type, sym_name[500]; unsigned long long sym_addr; diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index 864b36177424..b1bbbdcb7792 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -521,8 +521,6 @@ __s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name, typedef int (*kallsyms_cb_t)(unsigned long long sym_addr, char sym_type, const char *sym_name, void *ctx); -int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *arg); - /* handle direct returned errors */ static inline int libbpf_err(int ret) { From patchwork Thu Mar 21 20:01:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yonghong Song X-Patchwork-Id: 13599326 X-Patchwork-Delegate: bpf@iogearbox.net Received: from 66-220-155-179.mail-mxout.facebook.com (66-220-155-179.mail-mxout.facebook.com [66.220.155.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C6DD134422 for ; Thu, 21 Mar 2024 20:01:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.155.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051289; cv=none; b=Vc2VTOCw8lG3KtbtRBDcg0J91lnGaD65d3N0NPQyvcwMmGaCVzElg4HwWYNJvOkmuqaL8LUMAgLhfJqyw0LgQ8D9554fvF+g+bZyiMivRPx1bRCcdzS+rGcnEGvKMqaxKMmRlkya0LQfKL5n3+O9R8kdot4vdvP7Wf7SlEuzhOI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051289; c=relaxed/simple; bh=q8NPCLOPfVlm2bsd4mI05T7XTDGqlOt8r7v23lwuuxI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Pr1MUqNJlKNw+m/FP3IQQVufrTi4CCGwXP5eKs3Ep8VCKRAV1LXWb/9g+XslNoQgti98pj/Agd5sGsZzwCBaMQ55Li0vv77dfd6FwNOyIS4FygK1VQdVwUiat207GyunxmHq9oSnb7c4caNuwzsJzTHGvLTewUHpBTmOtSeuFXQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev; spf=fail smtp.mailfrom=linux.dev; arc=none smtp.client-ip=66.220.155.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=linux.dev Received: by devbig309.ftw3.facebook.com (Postfix, from userid 128203) id 10FFB2219081; Thu, 21 Mar 2024 13:01:14 -0700 (PDT) From: Yonghong Song To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , kernel-team@fb.com, Martin KaFai Lau Subject: [PATCH bpf-next v2 3/5] libbpf: Handle .llvm. symbol properly Date: Thu, 21 Mar 2024 13:01:14 -0700 Message-ID: <20240321200114.2219721-1-yonghong.song@linux.dev> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240321200058.2218328-1-yonghong.song@linux.dev> References: <20240321200058.2218328-1-yonghong.song@linux.dev> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net With CONFIG_LTO_CLANG_THIN enabled, with some of previous version of kernel code base ([1]), I hit the following error: 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.' ([2]) to 'bpf_link_fops' variable. Such renaming caused a problem in libbpf if 'bpf_link_fops' is used in bpf prog as a ksym as 'bpf_link_fops' does not match any symbol in /proc/kallsyms. To fix this issue, libbpf needs to understand that suffix '.llvm.' is caused by clang lto kernel and to process such symbols properly. With latest bpf-next code base built with CONFIG_LTO_CLANG_THIN, I cannot reproduce the above failure any more. But such an issue could happen with other symbols. For example, with my current kernel, I got the following from /proc/kallsyms: ffffffff84782154 d __func__.net_ratelimit.llvm.6135436931166841955 ffffffff85f0a500 d tk_core.llvm.726630847145216431 ffffffff85fdb960 d __fs_reclaim_map.llvm.10487989720912350772 ffffffff864c7300 d fake_dst_ops.llvm.54750082607048300 I could not easily create a selftest to test newly-added libbpf functionality with a static C test since I do not know which symbol is cross-file inlined. But based on my particular kernel, the following test change can run successfully. diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c index 6a86d1f07800..904a103f7b1d 100644 --- a/tools/testing/selftests/bpf/prog_tests/ksyms.c +++ b/tools/testing/selftests/bpf/prog_tests/ksyms.c @@ -42,6 +42,7 @@ void test_ksyms(void) 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_NEQ(data->out__fake_dst_ops, 0, "fake_dst_ops"); ASSERT_EQ(data->out__per_cpu_start, per_cpu_start_addr, "__per_cpu_start"); cleanup: diff --git a/tools/testing/selftests/bpf/progs/test_ksyms.c b/tools/testing/selftests/bpf/progs/test_ksyms.c index 6c9cbb5a3bdf..fe91eef54b66 100644 --- a/tools/testing/selftests/bpf/progs/test_ksyms.c +++ b/tools/testing/selftests/bpf/progs/test_ksyms.c @@ -9,11 +9,13 @@ __u64 out__bpf_link_fops = -1; __u64 out__bpf_link_fops1 = -1; __u64 out__btf_size = -1; __u64 out__per_cpu_start = -1; +__u64 out__fake_dst_ops = -1; extern const void bpf_link_fops __ksym; extern const void __start_BTF __ksym; extern const void __stop_BTF __ksym; extern const void __per_cpu_start __ksym; +extern const void fake_dst_ops __ksym; /* non-existing symbol, weak, default to zero */ extern const void bpf_link_fops1 __ksym __weak; @@ -23,6 +25,7 @@ int handler(const void *ctx) out__bpf_link_fops = (__u64)&bpf_link_fops; out__btf_size = (__u64)(&__stop_BTF - &__start_BTF); out__per_cpu_start = (__u64)&__per_cpu_start; + out__fake_dst_ops = (__u64)&fake_dst_ops; out__bpf_link_fops1 = (__u64)&bpf_link_fops1; This patch fixed the issue in libbpf such that if clang lto kernel is enabled and the symbol resolution is for ksym's, the suffix '.llvm.' will be ignored during comparison of bpf prog ksym vs. symbols in /proc/kallsyms, this resolved the issue. Note that currently kernel does not support gcc build with lto. [1] https://lore.kernel.org/bpf/20240302165017.1627295-1-yonghong.song@linux.dev/ [2] https://github.com/llvm/llvm-project/blob/release/18.x/llvm/include/llvm/IR/ModuleSummaryIndex.h#L1714-L1719 Signed-off-by: Yonghong Song --- tools/lib/bpf/libbpf.c | 64 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index a7a89269148c..8c3861192bc8 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -664,6 +664,7 @@ struct bpf_object { bool loaded; bool has_subcalls; bool has_rodata; + bool need_kallsyms; struct bpf_gen *gen_loader; @@ -8016,14 +8017,73 @@ static int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *ctx) return err; } +static 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_CLANG=y", 18)) { + check_lto = 1; + break; + } + } + + gzclose(file); +out: + return check_lto; +} + static int kallsyms_cb(unsigned long long sym_addr, char sym_type, const char *sym_name, void *ctx) { + int lto_enabled = check_lto_kernel(); + char orig_name[PATH_MAX], *res; struct bpf_object *obj = ctx; const struct btf_type *t; struct extern_desc *ext; - ext = find_extern_by_name(obj, sym_name); + /* Only check static variables in data sections */ + if (sym_type == 'd' && obj->need_kallsyms && lto_enabled == 1) { + strcpy(orig_name, sym_name); + res = strstr(orig_name, ".llvm."); + if (res) { + *res = '\0'; + pr_debug("extern (ksym) '%s': use original name '%s' for comparison\n", + sym_name, orig_name); + } + ext = find_extern_by_name(obj, orig_name); + } else { + ext = find_extern_by_name(obj, sym_name); + } if (!ext || ext->type != EXT_KSYM) return 0; @@ -8322,7 +8382,9 @@ static int bpf_object__resolve_externs(struct bpf_object *obj, return -EINVAL; } if (need_kallsyms) { + obj->need_kallsyms = true; err = bpf_object__read_kallsyms_file(obj); + obj->need_kallsyms = false; if (err) return -EINVAL; } From patchwork Thu Mar 21 20:01:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yonghong Song X-Patchwork-Id: 13599327 X-Patchwork-Delegate: bpf@iogearbox.net Received: from 69-171-232-181.mail-mxout.facebook.com (69-171-232-181.mail-mxout.facebook.com [69.171.232.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A06F13443B for ; Thu, 21 Mar 2024 20:01:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=69.171.232.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051292; cv=none; b=MW3Z/k4Hrac9peR1Eoxb07mVRewDpz9uUKXFHD3XJeJFL2J11YsIR62k3xC4x1mKsuFpFZeCYo2MYP7YqCMF89Lm/QaBkd6WHiZuKdisFPCdnzsXqNqdAGSd3ABofhTwT3Yw45uBcGLgGmmjTry1Vs/xqhCejHPjhPNVCh+OslI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051292; c=relaxed/simple; bh=I8cHHkO582AlMXZEe/J+OllEfpdNGNHr16UWvH57zzk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EM4SmoELvFykJFQZYp2Ada79vWOZGiboxXNo1+HGGxsEatA2VzMKJ3YL9EJZmbhR2DvYN3iNOxVDO1S1ySZn+eTNJXpu+r8cn6OeyY0NgjA3zLDoonqzePJsTOH8m11TDsrxK3Lff7gQFnLXqhcaLm+AApmLvnBis6oUvA6YEGg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev; spf=fail smtp.mailfrom=linux.dev; arc=none smtp.client-ip=69.171.232.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=linux.dev Received: by devbig309.ftw3.facebook.com (Postfix, from userid 128203) id 2A4852219097; Thu, 21 Mar 2024 13:01:19 -0700 (PDT) From: Yonghong Song To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , kernel-team@fb.com, Martin KaFai Lau Subject: [PATCH bpf-next v2 4/5] selftests/bpf: Fix kprobe_multi_bench_attach test failure with LTO kernel Date: Thu, 21 Mar 2024 13:01:19 -0700 Message-ID: <20240321200119.2220027-1-yonghong.song@linux.dev> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240321200058.2218328-1-yonghong.song@linux.dev> References: <20240321200058.2218328-1-yonghong.song@linux.dev> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net 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 #117/1 kprobe_multi_bench_attach/kernel:FAIL There are multiple symbols in /sys/kernel/debug/tracing/available_filter_functions are renamed in /proc/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. to prevent potential name collision. The kernel bpf_kprobe_multi_link_attach() and ftrace_lookup_symbols() try to find addresses based on /proc/kallsyms, hence the current test failed with LTO kenrel. 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: #117/1 kprobe_multi_bench_attach/kernel:OK Signed-off-by: Yonghong Song Acked-by: Jiri Olsa --- .../selftests/bpf/prog_tests/kprobe_multi_test.c | 12 ++++++++++++ 1 file changed, 12 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..f6130f4f3d88 100644 --- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c +++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c @@ -345,6 +345,9 @@ static int get_syms(char ***symsp, size_t *cntp, bool kernel) FILE *f; int err = 0; + if (!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 +396,15 @@ static int get_syms(char ***symsp, size_t *cntp, bool kernel) if (!strncmp(name, "__ftrace_invalid_address__", sizeof("__ftrace_invalid_address__") - 1)) continue; + /* + * In certain cases, e.g., clang lto kernel, the 'name' here + * may be different from the one in /proc/kallsyms due to + * /proc/kallsyms name might be ".llvm." instead + * of "". Exclude these 'name's since they will cause + * later kprobe_multi_attach failure. + */ + if (ksym_get_addr(name) == 0) + continue; err = hashmap__add(map, name, 0); if (err == -EEXIST) { From patchwork Thu Mar 21 20:01:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yonghong Song X-Patchwork-Id: 13599328 X-Patchwork-Delegate: bpf@iogearbox.net Received: from 66-220-155-178.mail-mxout.facebook.com (66-220-155-178.mail-mxout.facebook.com [66.220.155.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 56CB7134422 for ; Thu, 21 Mar 2024 20:01:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.155.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051299; cv=none; b=sYiFcZ6K9acfXsSeGMy4hjLftZyMRhO1W6Wa1vZYlnLmBWmCfUZbTbfiWHLDUHHR9ETGK48Z8Jjji1APzoH9T3R1f5t5SJxaA95uKuAzR9nGGZAnhO+yh1bmvLNTAq1Zq6RgvM9ptX8i42rkngYj3t1FnxEAvh8PfSagE/jE0ZQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711051299; c=relaxed/simple; bh=lwzIDjBWH2bW/fI6EM1MkhMhVQjwWu2r+y47owZB/Zk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YRWkb3/0Cys54B+SdpVXZcBZhDSQs+fIba5B2XRTtzecqk9V8osiOx+XVbgkuoKPeWSzDyy1LyStLegKM0n6b7AgIUJfOx/Z2kjwIwNwkctUWKfh+9Y6rz9qAL3Ivmktd6O9KtWXUwhfwZ9VnrXQD36VZkt3z19iwDb16CU4jFU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev; spf=fail smtp.mailfrom=linux.dev; arc=none smtp.client-ip=66.220.155.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=linux.dev Received: by devbig309.ftw3.facebook.com (Postfix, from userid 128203) id 4483A22190C3; Thu, 21 Mar 2024 13:01:24 -0700 (PDT) From: Yonghong Song To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , kernel-team@fb.com, Martin KaFai Lau Subject: [PATCH bpf-next v2 5/5] selftests/bpf: Add a selftest with available_filter_functions_addrs Date: Thu, 21 Mar 2024 13:01:24 -0700 Message-ID: <20240321200124.2220345-1-yonghong.song@linux.dev> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240321200058.2218328-1-yonghong.song@linux.dev> References: <20240321200058.2218328-1-yonghong.song@linux.dev> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net The current kprobe_multi_bench_attach/kernel test reads sym names from /sys/kernel/tracing/available_filter_functions. Some names do not agree with the corresponding entries in /proc/kallsyms since the corresponding /proc/kallsyms syms have suffix '.llvm.'. Actually, if we pass symbol names in /proc/kallsyms, kprobe_multi_attach will be okay. This patch added a new subtest where addresses are retrieved from /sys/kernel/tracing/available_filter_functions_addrs, and use the address to consule /proc/kallsyms to get the function name. Signed-off-by: Yonghong Song --- .../bpf/prog_tests/kprobe_multi_test.c | 139 ++++++++++++++++++ 1 file changed, 139 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 f6130f4f3d88..142309ced146 100644 --- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c +++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c @@ -438,6 +438,102 @@ static int get_syms(char ***symsp, size_t *cntp, bool kernel) return err; } +static int get_syms_from_addr(char ***symsp, size_t *cntp) +{ + char *name = NULL, **syms = NULL; + size_t cap = 0, cnt = 0, i; + struct hashmap *map; + struct ksym *ks; + char buf[256]; + FILE *f; + int err = 0; + void *addr; + + if (!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 + * interface. + * Filtering out duplicates by using hashmap__add, which won't + * add existing entry. + */ + + if (access("/sys/kernel/tracing/trace", F_OK) == 0) + f = fopen("/sys/kernel/tracing/available_filter_functions_addrs", "r"); + else + f = fopen("/sys/kernel/debug/tracing/available_filter_functions_addrs", "r"); + + if (!f) + return -ENOENT; + + map = hashmap__new(symbol_hash, symbol_equal, NULL); + if (IS_ERR(map)) { + err = libbpf_get_error(map); + goto error; + } + + while (fgets(buf, sizeof(buf), f)) { + if (strchr(buf, '[')) + continue; + + if (sscanf(buf, "%p$*[^\n]\n", &addr) != 1) + continue; + + ks = ksym_search((long)addr); + if (!ks) + return -EINVAL; + + name = ks->name; + + /* + * We attach to almost all kernel functions and some of them + * will cause 'suspicious RCU usage' when fprobe is attached + * to them. Filter out the current culprits - arch_cpu_idle + * default_idle and rcu_* functions. + */ + if (!strcmp(name, "arch_cpu_idle")) + continue; + if (!strcmp(name, "default_idle")) + continue; + if (!strncmp(name, "rcu_", 4)) + continue; + if (!strcmp(name, "bpf_dispatcher_xdp_func")) + continue; + if (!strncmp(name, "__ftrace_invalid_address__", + sizeof("__ftrace_invalid_address__") - 1)) + continue; + + err = hashmap__add(map, name, 0); + if (err == -EEXIST) { + err = 0; + continue; + } + if (err) + goto error; + + err = libbpf_ensure_mem((void **) &syms, &cap, + sizeof(*syms), cnt + 1); + if (err) + goto error; + + syms[cnt++] = name; + } + + *symsp = syms; + *cntp = cnt; + +error: + fclose(f); + hashmap__free(map); + if (err) { + for (i = 0; i < cnt; i++) + free(syms[i]); + free(syms); + } + return err; +} + static void test_kprobe_multi_bench_attach(bool kernel) { LIBBPF_OPTS(bpf_kprobe_multi_opts, opts); @@ -521,6 +617,47 @@ static void test_attach_override(void) kprobe_multi_override__destroy(skel); } +static void test_attach_kernel_addrs_to_sym(void) +{ + LIBBPF_OPTS(bpf_kprobe_multi_opts, opts); + struct kprobe_multi_empty *skel; + struct bpf_link *link; + char **syms = NULL; + size_t cnt = 0; + int i, err; + + err = get_syms_from_addr(&syms, &cnt); + if (err == -ENOENT) { + test__skip(); + return; + } + if (!ASSERT_OK(err, "get_syms_from_addr")) + return; + + skel = kprobe_multi_empty__open_and_load(); + if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load")) + goto cleanup; + + opts.syms = (const char **) syms; + opts.cnt = cnt; + + link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_empty, + NULL, &opts); + + if (!ASSERT_OK_PTR(link, "bpf_program__attach_kprobe_multi_opts")) + goto cleanup; + + bpf_link__destroy(link); + +cleanup: + kprobe_multi_empty__destroy(skel); + if (syms) { + for (i = 0; i < cnt; i++) + free(syms[i]); + free(syms); + } +} + void serial_test_kprobe_multi_bench_attach(void) { if (test__start_subtest("kernel")) @@ -550,4 +687,6 @@ void test_kprobe_multi_test(void) test_attach_api_fails(); if (test__start_subtest("attach_override")) test_attach_override(); + if (test__start_subtest("kernel_addrs_to_sym")) + test_attach_kernel_addrs_to_sym(); }