From: Leon Hwang <leon.hwang@linux.dev>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>,
Emil Tsalapatis <emil@etsalapatis.com>,
Ihor Solodrai <ihor.solodrai@linux.dev>,
Shuah Khan <shuah@kernel.org>, Leon Hwang <leon.hwang@linux.dev>,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [PATCH bpf-next] selftests/bpf: Move tracing_multi_bench_attach to bench
Date: Tue, 4 Aug 2026 23:48:13 +0800 [thread overview]
Message-ID: <20260804154813.90795-1-leon.hwang@linux.dev> (raw)
In CI, the tracing_multi_bench_attach test could cost >10s, which should
be avoided in daily CI running.
./test_progs -t tracing_multi_bench_attach -v
WATCHDOG: test case tracing_multi_bench_attach executes for 10 seconds...
serial_test_tracing_multi_bench_attach: found 40163 functions
serial_test_tracing_multi_bench_attach: attached in 9.367s
serial_test_tracing_multi_bench_attach: detached in 1.798s
#546 tracing_multi_bench_attach:OK
Since it is for benchmark attachment of tracing_multi link, move it to
the generic bench framework.
./bench tracing-multi-attach
Setting up benchmark 'tracing-multi-attach'...
tracing-multi-attach: found 40166 functions
tracing-multi-attach: attached in 9.278s
tracing-multi-attach: detached in 1.836s
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
tools/testing/selftests/bpf/Makefile | 2 +
tools/testing/selftests/bpf/bench.c | 2 +
.../bpf/benchs/bench_tracing_multi_attach.c | 177 ++++++++++++++++++
.../selftests/bpf/prog_tests/tracing_multi.c | 125 -------------
4 files changed, 181 insertions(+), 125 deletions(-)
create mode 100644 tools/testing/selftests/bpf/benchs/bench_tracing_multi_attach.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 55d394438705..e4d8cbd51d71 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -966,6 +966,7 @@ $(OUTPUT)/bench_ringbufs.o: $(OUTPUT)/ringbuf_bench.skel.h \
$(OUTPUT)/bench_bloom_filter_map.o: $(OUTPUT)/bloom_filter_bench.skel.h
$(OUTPUT)/bench_bpf_loop.o: $(OUTPUT)/bpf_loop_bench.skel.h
$(OUTPUT)/bench_strncmp.o: $(OUTPUT)/strncmp_bench.skel.h
+$(OUTPUT)/bench_tracing_multi_attach.o: $(OUTPUT)/tracing_multi_bench.skel.h
$(OUTPUT)/bench_bpf_hashmap_full_update.o: $(OUTPUT)/bpf_hashmap_full_update_bench.skel.h
$(OUTPUT)/bench_local_storage.o: $(OUTPUT)/local_storage_bench.skel.h
$(OUTPUT)/bench_local_storage_rcu_tasks_trace.o: $(OUTPUT)/local_storage_rcu_tasks_trace_bench.skel.h
@@ -991,6 +992,7 @@ $(OUTPUT)/bench: $(OUTPUT)/bench.o \
$(OUTPUT)/bench_bloom_filter_map.o \
$(OUTPUT)/bench_bpf_loop.o \
$(OUTPUT)/bench_strncmp.o \
+ $(OUTPUT)/bench_tracing_multi_attach.o \
$(OUTPUT)/bench_bpf_hashmap_full_update.o \
$(OUTPUT)/bench_local_storage.o \
$(OUTPUT)/bench_local_storage_rcu_tasks_trace.o \
diff --git a/tools/testing/selftests/bpf/bench.c b/tools/testing/selftests/bpf/bench.c
index 3d9d2cd7764b..5ce31459835c 100644
--- a/tools/testing/selftests/bpf/bench.c
+++ b/tools/testing/selftests/bpf/bench.c
@@ -545,6 +545,7 @@ extern const struct bench bench_trig_uprobe_multi_nop5;
extern const struct bench bench_trig_uretprobe_multi_nop5;
extern const struct bench bench_trig_usdt_nop;
extern const struct bench bench_trig_usdt_nop5;
+extern const struct bench bench_tracing_multi_attach;
#endif
extern const struct bench bench_rb_libbpf;
@@ -628,6 +629,7 @@ static const struct bench *benchs[] = {
&bench_trig_uretprobe_multi_nop5,
&bench_trig_usdt_nop,
&bench_trig_usdt_nop5,
+ &bench_tracing_multi_attach,
#endif
/* ringbuf/perfbuf benchmarks */
&bench_rb_libbpf,
diff --git a/tools/testing/selftests/bpf/benchs/bench_tracing_multi_attach.c b/tools/testing/selftests/bpf/benchs/bench_tracing_multi_attach.c
new file mode 100644
index 000000000000..7389d1742ddc
--- /dev/null
+++ b/tools/testing/selftests/bpf/benchs/bench_tracing_multi_attach.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <search.h>
+#include <stdio.h>
+#include <string.h>
+#include <bpf/btf.h>
+#include "bench.h"
+#include "testing_helpers.h"
+#include "trace_helpers.h"
+#include "tracing_multi_bench.skel.h"
+#include "bpf/libbpf_internal.h"
+
+static int compare(const void *ppa, const void *ppb)
+{
+ const char *pa = *(const char **)ppa;
+ const char *pb = *(const char **)ppb;
+
+ return strcmp(pa, pb);
+}
+
+static void tdestroy_free_nop(void *ptr)
+{
+}
+
+static void tracing_multi_attach_setup(void)
+{
+ LIBBPF_OPTS(bpf_tracing_multi_opts, opts);
+ struct tracing_multi_bench *skel = NULL;
+ long attach_start_ns, attach_end_ns;
+ long detach_start_ns, detach_end_ns;
+ double attach_delta, detach_delta;
+ struct bpf_link *link = NULL;
+ size_t i, cap = 0, cnt = 0;
+ struct ksyms *ksyms = NULL;
+ void *root = NULL;
+ void *dups = NULL;
+ __u32 *ids = NULL;
+ __u32 nr, type_id;
+ struct btf *btf;
+ int err;
+
+ setup_libbpf();
+
+ btf = btf__load_vmlinux_btf();
+ err = libbpf_get_error(btf);
+ if (err) {
+ btf = NULL;
+ fprintf(stderr, "failed to load vmlinux BTF: %s\n", strerror(-err));
+ goto cleanup;
+ }
+
+ skel = tracing_multi_bench__open_and_load();
+ err = libbpf_get_error(skel);
+ if (!skel) {
+ fprintf(stderr, "failed to open and load skeleton: %s\n", strerror(-err));
+ goto cleanup;
+ }
+
+ err = bpf_get_ksyms(&ksyms, true);
+ if (err) {
+ fprintf(stderr, "failed to get kernel symbols: %s\n", strerror(-err));
+ goto cleanup;
+ }
+
+ /* Get all ftrace 'safe' symbols.. */
+ for (i = 0; i < ksyms->filtered_cnt; i++) {
+ if (!tsearch(&ksyms->filtered_syms[i], &root, compare)) {
+ err = -ENOMEM;
+ fprintf(stderr, "failed to index ftrace symbols\n");
+ goto cleanup;
+ }
+ }
+
+ /*
+ * Collect names that are not unique in kallsyms. The kernel resolves a
+ * tracing-multi BTF id to an address with kallsyms_lookup_name(), which
+ * returns the first symbol of that name. For a duplicate name that may
+ * be a different (non-ftrace-able) instance than the ftrace-able one in
+ * available_filter_functions, so attaching to it by BTF id fails with
+ * -ENOENT (e.g. t_start/t_next/t_stop). ksyms->syms is sorted by name,
+ * so equal names are adjacent.
+ */
+ for (i = 1; i < ksyms->sym_cnt; i++) {
+ if (strcmp(ksyms->syms[i].name, ksyms->syms[i - 1].name))
+ continue;
+ if (!tsearch(&ksyms->syms[i].name, &dups, compare)) {
+ err = -ENOMEM;
+ fprintf(stderr, "failed to index duplicate kernel symbols\n");
+ goto cleanup;
+ }
+ }
+
+ /* ..and filter them through BTF and btf_type_is_traceable_func. */
+ nr = btf__type_cnt(btf);
+ for (type_id = 1; type_id < nr; type_id++) {
+ const struct btf_type *type;
+ const char *str;
+
+ type = btf__type_by_id(btf, type_id);
+ if (!type)
+ break;
+
+ if (BTF_INFO_KIND(type->info) != BTF_KIND_FUNC)
+ continue;
+
+ str = btf__name_by_offset(btf, type->name_off);
+ if (!str)
+ break;
+
+ if (!tfind(&str, &root, compare))
+ continue;
+
+ /* Skip names that are not unique in kallsyms, see above. */
+ if (tfind(&str, &dups, compare))
+ continue;
+
+ if (!btf_type_is_traceable_func(btf, type))
+ continue;
+
+ err = libbpf_ensure_mem((void **)&ids, &cap, sizeof(*ids), cnt + 1);
+ if (err) {
+ fprintf(stderr, "failed to allocate BTF ID array: %s\n",
+ strerror(-err));
+ goto cleanup;
+ }
+
+ ids[cnt++] = type_id;
+ }
+
+ opts.ids = ids;
+ opts.cnt = cnt;
+
+ attach_start_ns = get_time_ns();
+ link = bpf_program__attach_tracing_multi(skel->progs.bench, NULL, &opts);
+ attach_end_ns = get_time_ns();
+
+ err = libbpf_get_error(link);
+ if (err) {
+ link = NULL;
+ fprintf(stderr, "failed to attach tracing multi link: %s\n",
+ strerror(-err));
+ goto cleanup;
+ }
+
+ detach_start_ns = get_time_ns();
+ err = bpf_link__destroy(link);
+ detach_end_ns = get_time_ns();
+ link = NULL;
+ if (err) {
+ fprintf(stderr, "failed to detach tracing multi link: %s\n",
+ strerror(-err));
+ goto cleanup;
+ }
+
+ attach_delta = (attach_end_ns - attach_start_ns) / 1000000000.0;
+ detach_delta = (detach_end_ns - detach_start_ns) / 1000000000.0;
+
+ printf("%s: found %zu functions\n", bench->name, cnt);
+ printf("%s: attached in %7.3lfs\n", bench->name, attach_delta);
+ printf("%s: detached in %7.3lfs\n", bench->name, detach_delta);
+
+cleanup:
+ bpf_link__destroy(link);
+ tracing_multi_bench__destroy(skel);
+ tdestroy(root, tdestroy_free_nop);
+ tdestroy(dups, tdestroy_free_nop);
+ free_kallsyms_local(ksyms);
+ free(ids);
+ btf__free(btf);
+
+ exit(err ? 1 : 0);
+}
+
+const struct bench bench_tracing_multi_attach = {
+ .name = "tracing-multi-attach",
+ .setup = tracing_multi_attach_setup,
+};
diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_multi.c b/tools/testing/selftests/bpf/prog_tests/tracing_multi.c
index 0aa9532a05cf..fd4f256d2e0a 100644
--- a/tools/testing/selftests/bpf/prog_tests/tracing_multi.c
+++ b/tools/testing/selftests/bpf/prog_tests/tracing_multi.c
@@ -3,14 +3,12 @@
#include <test_progs.h>
#include <bpf/btf.h>
#include <search.h>
-#include "bpf/libbpf_internal.h"
#include "tracing_multi.skel.h"
#include "tracing_multi_module.skel.h"
#include "tracing_multi_intersect.skel.h"
#include "tracing_multi_session.skel.h"
#include "tracing_multi_fail.skel.h"
#include "tracing_multi_verifier.skel.h"
-#include "tracing_multi_bench.skel.h"
#include "tracing_multi_rollback.skel.h"
#include "trace_helpers.h"
@@ -662,129 +660,6 @@ static void test_attach_api_fails(void)
free(ids2);
}
-void serial_test_tracing_multi_bench_attach(void)
-{
- LIBBPF_OPTS(bpf_tracing_multi_opts, opts);
- struct tracing_multi_bench *skel = NULL;
- long attach_start_ns, attach_end_ns;
- long detach_start_ns, detach_end_ns;
- double attach_delta, detach_delta;
- struct bpf_link *link = NULL;
- size_t i, cap = 0, cnt = 0;
- struct ksyms *ksyms = NULL;
- void *root = NULL;
- void *dups = NULL;
- __u32 *ids = NULL;
- __u32 nr, type_id;
- struct btf *btf;
- int err;
-
-#ifndef __x86_64__
- test__skip();
- return;
-#endif
-
- btf = btf__load_vmlinux_btf();
- if (!ASSERT_OK_PTR(btf, "btf__load_vmlinux_btf"))
- return;
-
- skel = tracing_multi_bench__open_and_load();
- if (!ASSERT_OK_PTR(skel, "tracing_multi_bench__open_and_load"))
- goto cleanup;
-
- if (!ASSERT_OK(bpf_get_ksyms(&ksyms, true), "get_syms"))
- goto cleanup;
-
- /* Get all ftrace 'safe' symbols.. */
- for (i = 0; i < ksyms->filtered_cnt; i++) {
- if (!tsearch(&ksyms->filtered_syms[i], &root, compare)) {
- ASSERT_FAIL("tsearch failed");
- goto cleanup;
- }
- }
-
- /*
- * Collect names that are not unique in kallsyms. The kernel resolves a
- * tracing-multi BTF id to an address with kallsyms_lookup_name(), which
- * returns the first symbol of that name. For a duplicate name that may
- * be a different (non-ftrace-able) instance than the ftrace-able one in
- * available_filter_functions, so attaching to it by BTF id fails with
- * -ENOENT (e.g. t_start/t_next/t_stop). ksyms->syms is sorted by name,
- * so equal names are adjacent.
- */
- for (i = 1; i < ksyms->sym_cnt; i++) {
- if (strcmp(ksyms->syms[i].name, ksyms->syms[i - 1].name))
- continue;
- if (!tsearch(&ksyms->syms[i].name, &dups, compare)) {
- ASSERT_FAIL("tsearch failed");
- goto cleanup;
- }
- }
-
- /* ..and filter them through BTF and btf_type_is_traceable_func. */
- nr = btf__type_cnt(btf);
- for (type_id = 1; type_id < nr; type_id++) {
- const struct btf_type *type;
- const char *str;
-
- type = btf__type_by_id(btf, type_id);
- if (!type)
- break;
-
- if (BTF_INFO_KIND(type->info) != BTF_KIND_FUNC)
- continue;
-
- str = btf__name_by_offset(btf, type->name_off);
- if (!str)
- break;
-
- if (!tfind(&str, &root, compare))
- continue;
-
- /* Skip names that are not unique in kallsyms, see above. */
- if (tfind(&str, &dups, compare))
- continue;
-
- if (!btf_type_is_traceable_func(btf, type))
- continue;
-
- err = libbpf_ensure_mem((void **) &ids, &cap, sizeof(*ids), cnt + 1);
- if (err)
- goto cleanup;
-
- ids[cnt++] = type_id;
- }
-
- opts.ids = ids;
- opts.cnt = cnt;
-
- attach_start_ns = get_time_ns();
- link = bpf_program__attach_tracing_multi(skel->progs.bench, NULL, &opts);
- attach_end_ns = get_time_ns();
-
- if (!ASSERT_OK_PTR(link, "bpf_program__attach_tracing_multi"))
- goto cleanup;
-
- detach_start_ns = get_time_ns();
- bpf_link__destroy(link);
- detach_end_ns = get_time_ns();
-
- attach_delta = (attach_end_ns - attach_start_ns) / 1000000000.0;
- detach_delta = (detach_end_ns - detach_start_ns) / 1000000000.0;
-
- printf("%s: found %lu functions\n", __func__, cnt);
- printf("%s: attached in %7.3lfs\n", __func__, attach_delta);
- printf("%s: detached in %7.3lfs\n", __func__, detach_delta);
-
-cleanup:
- tracing_multi_bench__destroy(skel);
- tdestroy(root, tdestroy_free_nop);
- tdestroy(dups, tdestroy_free_nop);
- free_kallsyms_local(ksyms);
- free(ids);
- btf__free(btf);
-}
-
static void tracing_multi_rollback_run(struct tracing_multi_rollback *skel)
{
LIBBPF_OPTS(bpf_test_run_opts, topts);
--
2.55.0
next reply other threads:[~2026-08-04 15:48 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 15:48 Leon Hwang [this message]
2026-08-04 22:40 ` [PATCH bpf-next] selftests/bpf: Move tracing_multi_bench_attach to bench Andrii Nakryiko
2026-08-13 18:03 ` Jiri Olsa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260804154813.90795-1-leon.hwang@linux.dev \
--to=leon.hwang@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.