lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ