[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250528034712.138701-26-dongml2@chinatelecom.cn>
Date: Wed, 28 May 2025 11:47:12 +0800
From: Menglong Dong <menglong8.dong@...il.com>
To: alexei.starovoitov@...il.com,
rostedt@...dmis.org,
jolsa@...nel.org
Cc: bpf@...r.kernel.org,
Menglong Dong <dongml2@...natelecom.cn>,
linux-kernel@...r.kernel.org
Subject: [PATCH bpf-next 25/25] selftests/bpf: add performance bench test for trace prog
Add testcase for the performance of the trace bpf progs. In this testcase,
bpf_fentry_test1() will be called 10000000 times in bpf_testmod_bench_run,
and the time consumed will be returned. Following cases is considered:
- nop: nothing is attached to bpf_fentry_test1()
- fentry: a empty FENTRY bpf program is attached to bpf_fentry_test1()
- fentry_multi_single: a empty FENTRY_MULTI bpf program is attached to
bpf_fentry_test1()
- fentry_multi_all: a empty FENTRY_MULTI bpf program is attached to all
the kernel functions
- kprobe_multi_single: a empty KPROBE_MULTI bpf program is attached to
bpf_fentry_test1()
- kprobe_multi_all: a empty KPROBE_MULTI bpf program is attached to all
the kernel functions
And we can get the result by running:
./test_progs -t tracing_multi_bench -v | grep time
Signed-off-by: Menglong Dong <dongml2@...natelecom.cn>
---
.../selftests/bpf/prog_tests/trace_bench.c | 149 ++++++++++++++++++
.../selftests/bpf/progs/fentry_empty.c | 13 ++
.../testing/selftests/bpf/progs/trace_bench.c | 21 +++
.../selftests/bpf/test_kmods/bpf_testmod.c | 16 ++
4 files changed, 199 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/trace_bench.c
create mode 100644 tools/testing/selftests/bpf/progs/fentry_empty.c
create mode 100644 tools/testing/selftests/bpf/progs/trace_bench.c
diff --git a/tools/testing/selftests/bpf/prog_tests/trace_bench.c b/tools/testing/selftests/bpf/prog_tests/trace_bench.c
new file mode 100644
index 000000000000..673c9acf358c
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/trace_bench.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 ChinaTelecom */
+
+#include <test_progs.h>
+#include "bpf/libbpf_internal.h"
+
+#include "fentry_multi_empty.skel.h"
+#include "fentry_empty.skel.h"
+#include "kprobe_multi_empty.skel.h"
+#include "trace_bench.skel.h"
+
+static void test_bench_run(const char *name)
+{
+ struct trace_bench *skel;
+ __u64 bench_result;
+ int err;
+
+ skel = trace_bench__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "trace_bench__open_and_load"))
+ return;
+
+ err = trace_bench__attach(skel);
+ if (!ASSERT_OK(err, "trace_bench__attach"))
+ goto cleanup;
+
+ ASSERT_OK(trigger_module_test_read(1), "trigger_read");
+
+ bench_result = skel->bss->bench_result / 1000;
+ printf("bench time for %s: %lld.%03lldms\n", name, bench_result / 1000,
+ bench_result % 1000);
+cleanup:
+ trace_bench__destroy(skel);
+}
+
+static void test_fentry_multi(bool load_all, char *name)
+{
+ LIBBPF_OPTS(bpf_trace_multi_opts, opts);
+ struct fentry_multi_empty *skel;
+ char **syms = NULL;
+ struct bpf_link *link;
+ size_t cnt = 0;
+ int err;
+
+ skel = fentry_multi_empty__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "fentry_multi_empty__open_and_load"))
+ goto cleanup;
+
+ if (!load_all) {
+ err = fentry_multi_empty__attach(skel);
+ if (!ASSERT_OK(err, "fentry_multi_empty__attach"))
+ goto cleanup;
+ goto do_test;
+ }
+
+ if (!ASSERT_OK(bpf_get_ksyms(&syms, &cnt, true), "get_syms"))
+ return;
+ opts.syms = (const char **) syms;
+ opts.cnt = cnt;
+ opts.skip_invalid = true;
+ link = bpf_program__attach_trace_multi_opts(skel->progs.fentry_multi_empty,
+ &opts);
+ if (!ASSERT_OK_PTR(link, "bpf_program__attach_trace_multi_opts"))
+ goto cleanup;
+ skel->links.fentry_multi_empty = link;
+ printf("attach %d functions before testings\n", (int)opts.cnt);
+
+do_test:
+ test_bench_run(name);
+cleanup:
+ fentry_multi_empty__destroy(skel);
+ if (syms)
+ free(syms);
+}
+
+static void test_fentry_single(void)
+{
+ struct fentry_empty *skel;
+ int err;
+
+ skel = fentry_empty__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "fentry_empty__open_and_load"))
+ return;
+
+ err = fentry_empty__attach(skel);
+ if (!ASSERT_OK(err, "fentry_empty__attach"))
+ goto cleanup;
+
+ test_bench_run("fentry_single");
+cleanup:
+ fentry_empty__destroy(skel);
+}
+
+static void test_kprobe_multi(bool load_all, char *name)
+{
+ LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
+ char *test_func = "bpf_fentry_test1";
+ struct kprobe_multi_empty *skel;
+ struct bpf_link *link;
+ char **syms = NULL;
+ size_t cnt = 0;
+
+ if (!ASSERT_OK(bpf_get_ksyms(&syms, &cnt, true), "get_syms"))
+ return;
+
+ skel = kprobe_multi_empty__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
+ goto cleanup;
+
+ if (load_all) {
+ opts.syms = (const char **) syms;
+ opts.cnt = cnt;
+ } else {
+ opts.syms = (const char **) &test_func;
+ opts.cnt = 1;
+ }
+ 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;
+ skel->links.test_kprobe_empty = link;
+
+ if (load_all)
+ printf("attach %d functions before testings\n", (int)opts.cnt);
+ test_bench_run(name);
+
+cleanup:
+ kprobe_multi_empty__destroy(skel);
+ if (syms)
+ free(syms);
+}
+
+void test_trace_bench(void)
+{
+ if (test__start_subtest("nop"))
+ test_bench_run("nop");
+
+ if (test__start_subtest("fentry_single"))
+ test_fentry_single();
+
+ if (test__start_subtest("fentry_multi_single"))
+ test_fentry_multi(false, "fentry_multi_single");
+ if (test__start_subtest("fentry_multi_all"))
+ test_fentry_multi(true, "fentry_multi_all");
+
+ if (test__start_subtest("kprobe_multi_single"))
+ test_kprobe_multi(false, "kprobe_multi_single");
+ if (test__start_subtest("kprobe_multi_all"))
+ test_kprobe_multi(true, "kprobe_multi_all");
+}
diff --git a/tools/testing/selftests/bpf/progs/fentry_empty.c b/tools/testing/selftests/bpf/progs/fentry_empty.c
new file mode 100644
index 000000000000..f2bfaf04d56a
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/fentry_empty.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 ChinaTelecom */
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+char _license[] SEC("license") = "GPL";
+
+SEC("fentry/bpf_fentry_test1")
+int BPF_PROG(fentry_empty)
+{
+ return 0;
+}
diff --git a/tools/testing/selftests/bpf/progs/trace_bench.c b/tools/testing/selftests/bpf/progs/trace_bench.c
new file mode 100644
index 000000000000..98373871414a
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/trace_bench.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 ChinaTelecom */
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+char _license[] SEC("license") = "GPL";
+
+__u64 bench_result;
+
+SEC("fexit.multi/bpf_testmod_bench_run")
+int BPF_PROG(fexit_bench_done)
+{
+ __u64 ret = 0;
+
+ bpf_get_func_ret(ctx, &ret);
+ bench_result = ret;
+
+ return 0;
+}
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
index ebc4d5204136..d21775eba211 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -405,6 +405,20 @@ noinline int bpf_testmod_fentry_test11(u64 a, void *b, short c, int d,
return a + (long)b + c + d + (long)e + f + g + h + i + j + k;
}
+extern int bpf_fentry_test1(int a);
+noinline u64 bpf_testmod_bench_run(void)
+{
+ u64 start = ktime_get_boottime_ns();
+ u64 time;
+
+ for (int i = 0; i < 10000000; i++)
+ bpf_fentry_test1(i);
+
+ time = ktime_get_boottime_ns() - start;
+
+ return time;
+}
+
int bpf_testmod_fentry_ok;
noinline ssize_t
@@ -443,6 +457,8 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
(void)trace_bpf_testmod_test_raw_tp_null(NULL);
+ (void)bpf_testmod_bench_run();
+
bpf_testmod_test_struct_ops3();
struct_arg3 = kmalloc((sizeof(struct bpf_testmod_struct_arg_3) +
--
2.39.5
Powered by blists - more mailing lists