* [PATCH bpf-next 0/3] selftests/bpf: benchmark all symbols for kprobe-multi
@ 2025-08-19 3:39 Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 1/3] selftests/bpf: move get_ksyms and get_addrs to trace_helpers.c Menglong Dong
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Menglong Dong @ 2025-08-19 3:39 UTC (permalink / raw)
To: ast
Cc: daniel, andrii, martin.lau, eddyz87, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, mykolal, shuah,
davem, kuba, hawk, nathan, nick.desaulniers+lkml, morbo,
justinstitt, bpf, linux-kselftest, linux-kernel, netdev, llvm
Add the benchmark testcase "kprobe-multi-all", which will hook all the
kernel functions during the testing.
This series is separated out from [1].
Link: https://lore.kernel.org/bpf/20250817024607.296117-1-dongml2@chinatelecom.cn/ [1]
Menglong Dong (3):
selftests/bpf: move get_ksyms and get_addrs to trace_helpers.c
selftests/bpf: skip recursive functions for kprobe_multi
selftests/bpf: add benchmark testing for kprobe-multi-all
tools/testing/selftests/bpf/bench.c | 4 +
.../selftests/bpf/benchs/bench_trigger.c | 54 ++++
.../selftests/bpf/benchs/run_bench_trigger.sh | 4 +-
.../bpf/prog_tests/kprobe_multi_test.c | 220 +----------------
.../selftests/bpf/progs/trigger_bench.c | 12 +
tools/testing/selftests/bpf/trace_helpers.c | 233 ++++++++++++++++++
tools/testing/selftests/bpf/trace_helpers.h | 3 +
7 files changed, 311 insertions(+), 219 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH bpf-next 1/3] selftests/bpf: move get_ksyms and get_addrs to trace_helpers.c
2025-08-19 3:39 [PATCH bpf-next 0/3] selftests/bpf: benchmark all symbols for kprobe-multi Menglong Dong
@ 2025-08-19 3:39 ` Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 2/3] selftests/bpf: skip recursive functions for kprobe_multi Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 3/3] selftests/bpf: add benchmark testing for kprobe-multi-all Menglong Dong
2 siblings, 0 replies; 8+ messages in thread
From: Menglong Dong @ 2025-08-19 3:39 UTC (permalink / raw)
To: ast
Cc: daniel, andrii, martin.lau, eddyz87, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, mykolal, shuah,
davem, kuba, hawk, nathan, nick.desaulniers+lkml, morbo,
justinstitt, bpf, linux-kselftest, linux-kernel, netdev, llvm
We need to get all the kernel function that can be traced sometimes, so we
move the get_syms() and get_addrs() in kprobe_multi_test.c to
trace_helpers.c and rename it to bpf_get_ksyms() and bpf_get_addrs().
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
.../bpf/prog_tests/kprobe_multi_test.c | 220 +-----------------
tools/testing/selftests/bpf/trace_helpers.c | 214 +++++++++++++++++
tools/testing/selftests/bpf/trace_helpers.h | 3 +
3 files changed, 220 insertions(+), 217 deletions(-)
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 e19ef509ebf8..171706e78da8 100644
--- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
@@ -422,220 +422,6 @@ static void test_unique_match(void)
kprobe_multi__destroy(skel);
}
-static size_t symbol_hash(long key, void *ctx __maybe_unused)
-{
- return str_hash((const char *) key);
-}
-
-static bool symbol_equal(long key1, long key2, void *ctx __maybe_unused)
-{
- return strcmp((const char *) key1, (const char *) key2) == 0;
-}
-
-static bool is_invalid_entry(char *buf, bool kernel)
-{
- if (kernel && strchr(buf, '['))
- return true;
- if (!kernel && !strchr(buf, '['))
- return true;
- return false;
-}
-
-static bool skip_entry(char *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"))
- return true;
- if (!strcmp(name, "default_idle"))
- return true;
- if (!strncmp(name, "rcu_", 4))
- return true;
- if (!strcmp(name, "bpf_dispatcher_xdp_func"))
- return true;
- if (!strncmp(name, "__ftrace_invalid_address__",
- sizeof("__ftrace_invalid_address__") - 1))
- return true;
- return false;
-}
-
-/* Do comparision by ignoring '.llvm.<hash>' suffixes. */
-static int compare_name(const char *name1, const char *name2)
-{
- const char *res1, *res2;
- int len1, len2;
-
- res1 = strstr(name1, ".llvm.");
- res2 = strstr(name2, ".llvm.");
- len1 = res1 ? res1 - name1 : strlen(name1);
- len2 = res2 ? res2 - name2 : strlen(name2);
-
- if (len1 == len2)
- return strncmp(name1, name2, len1);
- if (len1 < len2)
- return strncmp(name1, name2, len1) <= 0 ? -1 : 1;
- return strncmp(name1, name2, len2) >= 0 ? 1 : -1;
-}
-
-static int load_kallsyms_compare(const void *p1, const void *p2)
-{
- return compare_name(((const struct ksym *)p1)->name, ((const struct ksym *)p2)->name);
-}
-
-static int search_kallsyms_compare(const void *p1, const struct ksym *p2)
-{
- return compare_name(p1, p2->name);
-}
-
-static int get_syms(char ***symsp, size_t *cntp, bool kernel)
-{
- size_t cap = 0, cnt = 0;
- char *name = NULL, *ksym_name, **syms = NULL;
- struct hashmap *map;
- struct ksyms *ksyms;
- struct ksym *ks;
- char buf[256];
- FILE *f;
- int err = 0;
-
- ksyms = load_kallsyms_custom_local(load_kallsyms_compare);
- if (!ASSERT_OK_PTR(ksyms, "load_kallsyms_custom_local"))
- 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", "r");
- else
- f = fopen("/sys/kernel/debug/tracing/available_filter_functions", "r");
-
- if (!f)
- return -EINVAL;
-
- 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 (is_invalid_entry(buf, kernel))
- continue;
-
- free(name);
- if (sscanf(buf, "%ms$*[^\n]\n", &name) != 1)
- continue;
- if (skip_entry(name))
- continue;
-
- ks = search_kallsyms_custom_local(ksyms, name, search_kallsyms_compare);
- if (!ks) {
- err = -EINVAL;
- goto error;
- }
-
- ksym_name = ks->name;
- err = hashmap__add(map, ksym_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++] = ksym_name;
- }
-
- *symsp = syms;
- *cntp = cnt;
-
-error:
- free(name);
- fclose(f);
- hashmap__free(map);
- if (err)
- free(syms);
- return err;
-}
-
-static int get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel)
-{
- unsigned long *addr, *addrs, *tmp_addrs;
- int err = 0, max_cnt, inc_cnt;
- char *name = NULL;
- size_t cnt = 0;
- char buf[256];
- FILE *f;
-
- 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;
-
- /* In my local setup, the number of entries is 50k+ so Let us initially
- * allocate space to hold 64k entries. If 64k is not enough, incrementally
- * increase 1k each time.
- */
- max_cnt = 65536;
- inc_cnt = 1024;
- addrs = malloc(max_cnt * sizeof(long));
- if (addrs == NULL) {
- err = -ENOMEM;
- goto error;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- if (is_invalid_entry(buf, kernel))
- continue;
-
- free(name);
- if (sscanf(buf, "%p %ms$*[^\n]\n", &addr, &name) != 2)
- continue;
- if (skip_entry(name))
- continue;
-
- if (cnt == max_cnt) {
- max_cnt += inc_cnt;
- tmp_addrs = realloc(addrs, max_cnt);
- if (!tmp_addrs) {
- err = -ENOMEM;
- goto error;
- }
- addrs = tmp_addrs;
- }
-
- addrs[cnt++] = (unsigned long)addr;
- }
-
- *addrsp = addrs;
- *cntp = cnt;
-
-error:
- free(name);
- fclose(f);
- if (err)
- free(addrs);
- return err;
-}
-
static void do_bench_test(struct kprobe_multi_empty *skel, struct bpf_kprobe_multi_opts *opts)
{
long attach_start_ns, attach_end_ns;
@@ -670,7 +456,7 @@ static void test_kprobe_multi_bench_attach(bool kernel)
char **syms = NULL;
size_t cnt = 0;
- if (!ASSERT_OK(get_syms(&syms, &cnt, kernel), "get_syms"))
+ if (!ASSERT_OK(bpf_get_ksyms(&syms, &cnt, kernel), "bpf_get_ksyms"))
return;
skel = kprobe_multi_empty__open_and_load();
@@ -696,13 +482,13 @@ static void test_kprobe_multi_bench_attach_addr(bool kernel)
size_t cnt = 0;
int err;
- err = get_addrs(&addrs, &cnt, kernel);
+ err = bpf_get_addrs(&addrs, &cnt, kernel);
if (err == -ENOENT) {
test__skip();
return;
}
- if (!ASSERT_OK(err, "get_addrs"))
+ if (!ASSERT_OK(err, "bpf_get_addrs"))
return;
skel = kprobe_multi_empty__open_and_load();
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
index 81943c6254e6..d24baf244d1f 100644
--- a/tools/testing/selftests/bpf/trace_helpers.c
+++ b/tools/testing/selftests/bpf/trace_helpers.c
@@ -17,6 +17,7 @@
#include <linux/limits.h>
#include <libelf.h>
#include <gelf.h>
+#include "bpf/hashmap.h"
#include "bpf/libbpf_internal.h"
#define TRACEFS_PIPE "/sys/kernel/tracing/trace_pipe"
@@ -519,3 +520,216 @@ void read_trace_pipe(void)
{
read_trace_pipe_iter(trace_pipe_cb, NULL, 0);
}
+
+static size_t symbol_hash(long key, void *ctx __maybe_unused)
+{
+ return str_hash((const char *) key);
+}
+
+static bool symbol_equal(long key1, long key2, void *ctx __maybe_unused)
+{
+ return strcmp((const char *) key1, (const char *) key2) == 0;
+}
+
+static bool is_invalid_entry(char *buf, bool kernel)
+{
+ if (kernel && strchr(buf, '['))
+ return true;
+ if (!kernel && !strchr(buf, '['))
+ return true;
+ return false;
+}
+
+static bool skip_entry(char *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"))
+ return true;
+ if (!strcmp(name, "default_idle"))
+ return true;
+ if (!strncmp(name, "rcu_", 4))
+ return true;
+ if (!strcmp(name, "bpf_dispatcher_xdp_func"))
+ return true;
+ if (!strncmp(name, "__ftrace_invalid_address__",
+ sizeof("__ftrace_invalid_address__") - 1))
+ return true;
+ return false;
+}
+
+/* Do comparison by ignoring '.llvm.<hash>' suffixes. */
+static int compare_name(const char *name1, const char *name2)
+{
+ const char *res1, *res2;
+ int len1, len2;
+
+ res1 = strstr(name1, ".llvm.");
+ res2 = strstr(name2, ".llvm.");
+ len1 = res1 ? res1 - name1 : strlen(name1);
+ len2 = res2 ? res2 - name2 : strlen(name2);
+
+ if (len1 == len2)
+ return strncmp(name1, name2, len1);
+ if (len1 < len2)
+ return strncmp(name1, name2, len1) <= 0 ? -1 : 1;
+ return strncmp(name1, name2, len2) >= 0 ? 1 : -1;
+}
+
+static int load_kallsyms_compare(const void *p1, const void *p2)
+{
+ return compare_name(((const struct ksym *)p1)->name, ((const struct ksym *)p2)->name);
+}
+
+static int search_kallsyms_compare(const void *p1, const struct ksym *p2)
+{
+ return compare_name(p1, p2->name);
+}
+
+int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel)
+{
+ size_t cap = 0, cnt = 0;
+ char *name = NULL, *ksym_name, **syms = NULL;
+ struct hashmap *map;
+ struct ksyms *ksyms;
+ struct ksym *ks;
+ char buf[256];
+ FILE *f;
+ int err = 0;
+
+ ksyms = load_kallsyms_custom_local(load_kallsyms_compare);
+ if (!ksyms)
+ return -EINVAL;
+
+ /*
+ * The available_filter_functions contains many duplicates,
+ * but other than that all symbols are usable to trace.
+ * 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", "r");
+ else
+ f = fopen("/sys/kernel/debug/tracing/available_filter_functions", "r");
+
+ if (!f)
+ return -EINVAL;
+
+ 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 (is_invalid_entry(buf, kernel))
+ continue;
+
+ free(name);
+ if (sscanf(buf, "%ms$*[^\n]\n", &name) != 1)
+ continue;
+ if (skip_entry(name))
+ continue;
+
+ ks = search_kallsyms_custom_local(ksyms, name, search_kallsyms_compare);
+ if (!ks) {
+ err = -EINVAL;
+ goto error;
+ }
+
+ ksym_name = ks->name;
+ err = hashmap__add(map, ksym_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++] = ksym_name;
+ }
+
+ *symsp = syms;
+ *cntp = cnt;
+
+error:
+ free(name);
+ fclose(f);
+ hashmap__free(map);
+ if (err)
+ free(syms);
+ return err;
+}
+
+int bpf_get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel)
+{
+ unsigned long *addr, *addrs, *tmp_addrs;
+ int err = 0, max_cnt, inc_cnt;
+ char *name = NULL;
+ size_t cnt = 0;
+ char buf[256];
+ FILE *f;
+
+ 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;
+
+ /* In my local setup, the number of entries is 50k+ so Let us initially
+ * allocate space to hold 64k entries. If 64k is not enough, incrementally
+ * increase 1k each time.
+ */
+ max_cnt = 65536;
+ inc_cnt = 1024;
+ addrs = malloc(max_cnt * sizeof(long));
+ if (addrs == NULL) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ while (fgets(buf, sizeof(buf), f)) {
+ if (is_invalid_entry(buf, kernel))
+ continue;
+
+ free(name);
+ if (sscanf(buf, "%p %ms$*[^\n]\n", &addr, &name) != 2)
+ continue;
+ if (skip_entry(name))
+ continue;
+
+ if (cnt == max_cnt) {
+ max_cnt += inc_cnt;
+ tmp_addrs = realloc(addrs, max_cnt);
+ if (!tmp_addrs) {
+ err = -ENOMEM;
+ goto error;
+ }
+ addrs = tmp_addrs;
+ }
+
+ addrs[cnt++] = (unsigned long)addr;
+ }
+
+ *addrsp = addrs;
+ *cntp = cnt;
+
+error:
+ free(name);
+ fclose(f);
+ if (err)
+ free(addrs);
+ return err;
+}
diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
index 2ce873c9f9aa..9437bdd4afa5 100644
--- a/tools/testing/selftests/bpf/trace_helpers.h
+++ b/tools/testing/selftests/bpf/trace_helpers.h
@@ -41,4 +41,7 @@ ssize_t get_rel_offset(uintptr_t addr);
int read_build_id(const char *path, char *build_id, size_t size);
+int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel);
+int bpf_get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel);
+
#endif
--
2.50.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next 2/3] selftests/bpf: skip recursive functions for kprobe_multi
2025-08-19 3:39 [PATCH bpf-next 0/3] selftests/bpf: benchmark all symbols for kprobe-multi Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 1/3] selftests/bpf: move get_ksyms and get_addrs to trace_helpers.c Menglong Dong
@ 2025-08-19 3:39 ` Menglong Dong
2025-08-20 22:47 ` Andrii Nakryiko
2025-08-19 3:39 ` [PATCH bpf-next 3/3] selftests/bpf: add benchmark testing for kprobe-multi-all Menglong Dong
2 siblings, 1 reply; 8+ messages in thread
From: Menglong Dong @ 2025-08-19 3:39 UTC (permalink / raw)
To: ast
Cc: daniel, andrii, martin.lau, eddyz87, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, mykolal, shuah,
davem, kuba, hawk, nathan, nick.desaulniers+lkml, morbo,
justinstitt, bpf, linux-kselftest, linux-kernel, netdev, llvm
Some functions is recursive for the kprobe_multi and impact the benchmark
results. So just skip them.
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
tools/testing/selftests/bpf/trace_helpers.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
index d24baf244d1f..9da9da51b132 100644
--- a/tools/testing/selftests/bpf/trace_helpers.c
+++ b/tools/testing/selftests/bpf/trace_helpers.c
@@ -559,6 +559,22 @@ static bool skip_entry(char *name)
if (!strncmp(name, "__ftrace_invalid_address__",
sizeof("__ftrace_invalid_address__") - 1))
return true;
+
+ if (!strcmp(name, "migrate_disable"))
+ return true;
+ if (!strcmp(name, "migrate_enable"))
+ return true;
+ if (!strcmp(name, "rcu_read_unlock_strict"))
+ return true;
+ if (!strcmp(name, "preempt_count_add"))
+ return true;
+ if (!strcmp(name, "preempt_count_sub"))
+ return true;
+ if (!strcmp(name, "__rcu_read_lock"))
+ return true;
+ if (!strcmp(name, "__rcu_read_unlock"))
+ return true;
+
return false;
}
--
2.50.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next 3/3] selftests/bpf: add benchmark testing for kprobe-multi-all
2025-08-19 3:39 [PATCH bpf-next 0/3] selftests/bpf: benchmark all symbols for kprobe-multi Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 1/3] selftests/bpf: move get_ksyms and get_addrs to trace_helpers.c Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 2/3] selftests/bpf: skip recursive functions for kprobe_multi Menglong Dong
@ 2025-08-19 3:39 ` Menglong Dong
2025-08-20 22:53 ` Andrii Nakryiko
2 siblings, 1 reply; 8+ messages in thread
From: Menglong Dong @ 2025-08-19 3:39 UTC (permalink / raw)
To: ast
Cc: daniel, andrii, martin.lau, eddyz87, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, mykolal, shuah,
davem, kuba, hawk, nathan, nick.desaulniers+lkml, morbo,
justinstitt, bpf, linux-kselftest, linux-kernel, netdev, llvm
For now, the benchmark for kprobe-multi is single, which means there is
only 1 function is hooked during testing. Add the testing
"kprobe-multi-all", which will hook all the kernel functions during
the benchmark. And the "kretprobe-multi-all" is added too.
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
tools/testing/selftests/bpf/bench.c | 4 ++
.../selftests/bpf/benchs/bench_trigger.c | 54 +++++++++++++++++++
.../selftests/bpf/benchs/run_bench_trigger.sh | 4 +-
.../selftests/bpf/progs/trigger_bench.c | 12 +++++
tools/testing/selftests/bpf/trace_helpers.c | 3 ++
5 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/bench.c b/tools/testing/selftests/bpf/bench.c
index ddd73d06a1eb..29dbf937818a 100644
--- a/tools/testing/selftests/bpf/bench.c
+++ b/tools/testing/selftests/bpf/bench.c
@@ -510,6 +510,8 @@ extern const struct bench bench_trig_kretprobe;
extern const struct bench bench_trig_kprobe_multi;
extern const struct bench bench_trig_kretprobe_multi;
extern const struct bench bench_trig_fentry;
+extern const struct bench bench_trig_kprobe_multi_all;
+extern const struct bench bench_trig_kretprobe_multi_all;
extern const struct bench bench_trig_fexit;
extern const struct bench bench_trig_fmodret;
extern const struct bench bench_trig_tp;
@@ -578,6 +580,8 @@ static const struct bench *benchs[] = {
&bench_trig_kprobe_multi,
&bench_trig_kretprobe_multi,
&bench_trig_fentry,
+ &bench_trig_kprobe_multi_all,
+ &bench_trig_kretprobe_multi_all,
&bench_trig_fexit,
&bench_trig_fmodret,
&bench_trig_tp,
diff --git a/tools/testing/selftests/bpf/benchs/bench_trigger.c b/tools/testing/selftests/bpf/benchs/bench_trigger.c
index 82327657846e..c6634a64a7c0 100644
--- a/tools/testing/selftests/bpf/benchs/bench_trigger.c
+++ b/tools/testing/selftests/bpf/benchs/bench_trigger.c
@@ -226,6 +226,58 @@ static void trigger_fentry_setup(void)
attach_bpf(ctx.skel->progs.bench_trigger_fentry);
}
+static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe)
+{
+ LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
+ char **syms = NULL;
+ size_t cnt = 0;
+
+ if (bpf_get_ksyms(&syms, &cnt, true)) {
+ printf("failed to get ksyms\n");
+ exit(1);
+ }
+
+ printf("found %zu ksyms\n", cnt);
+ opts.syms = (const char **) syms;
+ opts.cnt = cnt;
+ opts.retprobe = kretprobe;
+ /* attach empty to all the kernel functions except bpf_get_numa_node_id. */
+ if (!bpf_program__attach_kprobe_multi_opts(empty, NULL, &opts)) {
+ printf("failed to attach bpf_program__attach_kprobe_multi_opts to all\n");
+ exit(1);
+ }
+}
+
+static void trigger_kprobe_multi_all_setup(void)
+{
+ struct bpf_program *prog, *empty;
+
+ setup_ctx();
+ empty = ctx.skel->progs.bench_kprobe_multi_empty;
+ prog = ctx.skel->progs.bench_trigger_kprobe_multi;
+ bpf_program__set_autoload(empty, true);
+ bpf_program__set_autoload(prog, true);
+ load_ctx();
+
+ attach_ksyms_all(empty, false);
+ attach_bpf(prog);
+}
+
+static void trigger_kretprobe_multi_all_setup(void)
+{
+ struct bpf_program *prog, *empty;
+
+ setup_ctx();
+ empty = ctx.skel->progs.bench_kretprobe_multi_empty;
+ prog = ctx.skel->progs.bench_trigger_kretprobe_multi;
+ bpf_program__set_autoload(empty, true);
+ bpf_program__set_autoload(prog, true);
+ load_ctx();
+
+ attach_ksyms_all(empty, true);
+ attach_bpf(prog);
+}
+
static void trigger_fexit_setup(void)
{
setup_ctx();
@@ -512,6 +564,8 @@ BENCH_TRIG_KERNEL(kretprobe, "kretprobe");
BENCH_TRIG_KERNEL(kprobe_multi, "kprobe-multi");
BENCH_TRIG_KERNEL(kretprobe_multi, "kretprobe-multi");
BENCH_TRIG_KERNEL(fentry, "fentry");
+BENCH_TRIG_KERNEL(kprobe_multi_all, "kprobe-multi-all");
+BENCH_TRIG_KERNEL(kretprobe_multi_all, "kretprobe-multi-all");
BENCH_TRIG_KERNEL(fexit, "fexit");
BENCH_TRIG_KERNEL(fmodret, "fmodret");
BENCH_TRIG_KERNEL(tp, "tp");
diff --git a/tools/testing/selftests/bpf/benchs/run_bench_trigger.sh b/tools/testing/selftests/bpf/benchs/run_bench_trigger.sh
index a690f5a68b6b..f7573708a0c3 100755
--- a/tools/testing/selftests/bpf/benchs/run_bench_trigger.sh
+++ b/tools/testing/selftests/bpf/benchs/run_bench_trigger.sh
@@ -6,8 +6,8 @@ def_tests=( \
usermode-count kernel-count syscall-count \
fentry fexit fmodret \
rawtp tp \
- kprobe kprobe-multi \
- kretprobe kretprobe-multi \
+ kprobe kprobe-multi kprobe-multi-all \
+ kretprobe kretprobe-multi kretprobe-multi-all \
)
tests=("$@")
diff --git a/tools/testing/selftests/bpf/progs/trigger_bench.c b/tools/testing/selftests/bpf/progs/trigger_bench.c
index 044a6d78923e..3d5f30c29ae3 100644
--- a/tools/testing/selftests/bpf/progs/trigger_bench.c
+++ b/tools/testing/selftests/bpf/progs/trigger_bench.c
@@ -97,6 +97,12 @@ int bench_trigger_kprobe_multi(void *ctx)
return 0;
}
+SEC("?kprobe.multi/bpf_get_numa_node_id")
+int bench_kprobe_multi_empty(void *ctx)
+{
+ return 0;
+}
+
SEC("?kretprobe.multi/bpf_get_numa_node_id")
int bench_trigger_kretprobe_multi(void *ctx)
{
@@ -104,6 +110,12 @@ int bench_trigger_kretprobe_multi(void *ctx)
return 0;
}
+SEC("?kretprobe.multi/bpf_get_numa_node_id")
+int bench_kretprobe_multi_empty(void *ctx)
+{
+ return 0;
+}
+
SEC("?fentry/bpf_get_numa_node_id")
int bench_trigger_fentry(void *ctx)
{
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
index 9da9da51b132..78cf1aab09d8 100644
--- a/tools/testing/selftests/bpf/trace_helpers.c
+++ b/tools/testing/selftests/bpf/trace_helpers.c
@@ -575,6 +575,9 @@ static bool skip_entry(char *name)
if (!strcmp(name, "__rcu_read_unlock"))
return true;
+ if (!strcmp(name, "bpf_get_numa_node_id"))
+ return true;
+
return false;
}
--
2.50.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 2/3] selftests/bpf: skip recursive functions for kprobe_multi
2025-08-19 3:39 ` [PATCH bpf-next 2/3] selftests/bpf: skip recursive functions for kprobe_multi Menglong Dong
@ 2025-08-20 22:47 ` Andrii Nakryiko
2025-08-21 1:39 ` Menglong Dong
0 siblings, 1 reply; 8+ messages in thread
From: Andrii Nakryiko @ 2025-08-20 22:47 UTC (permalink / raw)
To: Menglong Dong
Cc: ast, daniel, andrii, martin.lau, eddyz87, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, mykolal, shuah,
davem, kuba, hawk, nathan, nick.desaulniers+lkml, morbo,
justinstitt, bpf, linux-kselftest, linux-kernel, netdev, llvm
On Mon, Aug 18, 2025 at 8:40 PM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> Some functions is recursive for the kprobe_multi and impact the benchmark
> results. So just skip them.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
> tools/testing/selftests/bpf/trace_helpers.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
> index d24baf244d1f..9da9da51b132 100644
> --- a/tools/testing/selftests/bpf/trace_helpers.c
> +++ b/tools/testing/selftests/bpf/trace_helpers.c
> @@ -559,6 +559,22 @@ static bool skip_entry(char *name)
> if (!strncmp(name, "__ftrace_invalid_address__",
> sizeof("__ftrace_invalid_address__") - 1))
> return true;
> +
> + if (!strcmp(name, "migrate_disable"))
> + return true;
> + if (!strcmp(name, "migrate_enable"))
> + return true;
> + if (!strcmp(name, "rcu_read_unlock_strict"))
> + return true;
> + if (!strcmp(name, "preempt_count_add"))
> + return true;
> + if (!strcmp(name, "preempt_count_sub"))
> + return true;
> + if (!strcmp(name, "__rcu_read_lock"))
> + return true;
> + if (!strcmp(name, "__rcu_read_unlock"))
> + return true;
> +
static const char *trace_blacklist[] = {
"migrate_disable",
"migrate_enable",
...
};
it's not like it's one or two functions where copy-pasting strcmp might be fine
pw-bot: cr
> return false;
> }
>
> --
> 2.50.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 3/3] selftests/bpf: add benchmark testing for kprobe-multi-all
2025-08-19 3:39 ` [PATCH bpf-next 3/3] selftests/bpf: add benchmark testing for kprobe-multi-all Menglong Dong
@ 2025-08-20 22:53 ` Andrii Nakryiko
2025-08-21 1:40 ` Menglong Dong
0 siblings, 1 reply; 8+ messages in thread
From: Andrii Nakryiko @ 2025-08-20 22:53 UTC (permalink / raw)
To: Menglong Dong
Cc: ast, daniel, andrii, martin.lau, eddyz87, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, mykolal, shuah,
davem, kuba, hawk, nathan, nick.desaulniers+lkml, morbo,
justinstitt, bpf, linux-kselftest, linux-kernel, netdev, llvm
On Mon, Aug 18, 2025 at 8:40 PM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> For now, the benchmark for kprobe-multi is single, which means there is
> only 1 function is hooked during testing. Add the testing
> "kprobe-multi-all", which will hook all the kernel functions during
> the benchmark. And the "kretprobe-multi-all" is added too.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
> tools/testing/selftests/bpf/bench.c | 4 ++
> .../selftests/bpf/benchs/bench_trigger.c | 54 +++++++++++++++++++
> .../selftests/bpf/benchs/run_bench_trigger.sh | 4 +-
> .../selftests/bpf/progs/trigger_bench.c | 12 +++++
> tools/testing/selftests/bpf/trace_helpers.c | 3 ++
> 5 files changed, 75 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/bench.c b/tools/testing/selftests/bpf/bench.c
> index ddd73d06a1eb..29dbf937818a 100644
> --- a/tools/testing/selftests/bpf/bench.c
> +++ b/tools/testing/selftests/bpf/bench.c
> @@ -510,6 +510,8 @@ extern const struct bench bench_trig_kretprobe;
> extern const struct bench bench_trig_kprobe_multi;
> extern const struct bench bench_trig_kretprobe_multi;
> extern const struct bench bench_trig_fentry;
> +extern const struct bench bench_trig_kprobe_multi_all;
> +extern const struct bench bench_trig_kretprobe_multi_all;
> extern const struct bench bench_trig_fexit;
> extern const struct bench bench_trig_fmodret;
> extern const struct bench bench_trig_tp;
> @@ -578,6 +580,8 @@ static const struct bench *benchs[] = {
> &bench_trig_kprobe_multi,
> &bench_trig_kretprobe_multi,
> &bench_trig_fentry,
> + &bench_trig_kprobe_multi_all,
> + &bench_trig_kretprobe_multi_all,
> &bench_trig_fexit,
> &bench_trig_fmodret,
> &bench_trig_tp,
> diff --git a/tools/testing/selftests/bpf/benchs/bench_trigger.c b/tools/testing/selftests/bpf/benchs/bench_trigger.c
> index 82327657846e..c6634a64a7c0 100644
> --- a/tools/testing/selftests/bpf/benchs/bench_trigger.c
> +++ b/tools/testing/selftests/bpf/benchs/bench_trigger.c
> @@ -226,6 +226,58 @@ static void trigger_fentry_setup(void)
> attach_bpf(ctx.skel->progs.bench_trigger_fentry);
> }
>
> +static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe)
> +{
> + LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
> + char **syms = NULL;
> + size_t cnt = 0;
> +
> + if (bpf_get_ksyms(&syms, &cnt, true)) {
> + printf("failed to get ksyms\n");
we seem to be using fprintf(stderr, "...") for emitting errors like
this (at least in some benchmarks, and it makes sense to me). Do the
same?
> + exit(1);
> + }
> +
> + printf("found %zu ksyms\n", cnt);
stray debug output?
> + opts.syms = (const char **) syms;
> + opts.cnt = cnt;
> + opts.retprobe = kretprobe;
> + /* attach empty to all the kernel functions except bpf_get_numa_node_id. */
> + if (!bpf_program__attach_kprobe_multi_opts(empty, NULL, &opts)) {
> + printf("failed to attach bpf_program__attach_kprobe_multi_opts to all\n");
> + exit(1);
> + }
> +}
> +
[...]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 2/3] selftests/bpf: skip recursive functions for kprobe_multi
2025-08-20 22:47 ` Andrii Nakryiko
@ 2025-08-21 1:39 ` Menglong Dong
0 siblings, 0 replies; 8+ messages in thread
From: Menglong Dong @ 2025-08-21 1:39 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: ast, daniel, andrii, martin.lau, eddyz87, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, mykolal, shuah,
davem, kuba, hawk, nathan, nick.desaulniers+lkml, morbo,
justinstitt, bpf, linux-kselftest, linux-kernel, netdev, llvm
On Thu, Aug 21, 2025 at 6:47 AM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Mon, Aug 18, 2025 at 8:40 PM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > Some functions is recursive for the kprobe_multi and impact the benchmark
> > results. So just skip them.
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> > tools/testing/selftests/bpf/trace_helpers.c | 16 ++++++++++++++++
> > 1 file changed, 16 insertions(+)
> >
> > diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
> > index d24baf244d1f..9da9da51b132 100644
> > --- a/tools/testing/selftests/bpf/trace_helpers.c
> > +++ b/tools/testing/selftests/bpf/trace_helpers.c
> > @@ -559,6 +559,22 @@ static bool skip_entry(char *name)
> > if (!strncmp(name, "__ftrace_invalid_address__",
> > sizeof("__ftrace_invalid_address__") - 1))
> > return true;
> > +
> > + if (!strcmp(name, "migrate_disable"))
> > + return true;
> > + if (!strcmp(name, "migrate_enable"))
> > + return true;
> > + if (!strcmp(name, "rcu_read_unlock_strict"))
> > + return true;
> > + if (!strcmp(name, "preempt_count_add"))
> > + return true;
> > + if (!strcmp(name, "preempt_count_sub"))
> > + return true;
> > + if (!strcmp(name, "__rcu_read_lock"))
> > + return true;
> > + if (!strcmp(name, "__rcu_read_unlock"))
> > + return true;
> > +
>
> static const char *trace_blacklist[] = {
> "migrate_disable",
> "migrate_enable",
> ...
> };
>
> it's not like it's one or two functions where copy-pasting strcmp might be fine
OK!
>
> pw-bot: cr
>
>
> > return false;
> > }
> >
> > --
> > 2.50.1
> >
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH bpf-next 3/3] selftests/bpf: add benchmark testing for kprobe-multi-all
2025-08-20 22:53 ` Andrii Nakryiko
@ 2025-08-21 1:40 ` Menglong Dong
0 siblings, 0 replies; 8+ messages in thread
From: Menglong Dong @ 2025-08-21 1:40 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: ast, daniel, andrii, martin.lau, eddyz87, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, mykolal, shuah,
davem, kuba, hawk, nathan, nick.desaulniers+lkml, morbo,
justinstitt, bpf, linux-kselftest, linux-kernel, netdev, llvm
On Thu, Aug 21, 2025 at 6:54 AM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Mon, Aug 18, 2025 at 8:40 PM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > For now, the benchmark for kprobe-multi is single, which means there is
> > only 1 function is hooked during testing. Add the testing
> > "kprobe-multi-all", which will hook all the kernel functions during
> > the benchmark. And the "kretprobe-multi-all" is added too.
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> > tools/testing/selftests/bpf/bench.c | 4 ++
> > .../selftests/bpf/benchs/bench_trigger.c | 54 +++++++++++++++++++
> > .../selftests/bpf/benchs/run_bench_trigger.sh | 4 +-
> > .../selftests/bpf/progs/trigger_bench.c | 12 +++++
> > tools/testing/selftests/bpf/trace_helpers.c | 3 ++
> > 5 files changed, 75 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/testing/selftests/bpf/bench.c b/tools/testing/selftests/bpf/bench.c
> > index ddd73d06a1eb..29dbf937818a 100644
> > --- a/tools/testing/selftests/bpf/bench.c
> > +++ b/tools/testing/selftests/bpf/bench.c
> > @@ -510,6 +510,8 @@ extern const struct bench bench_trig_kretprobe;
> > extern const struct bench bench_trig_kprobe_multi;
> > extern const struct bench bench_trig_kretprobe_multi;
> > extern const struct bench bench_trig_fentry;
> > +extern const struct bench bench_trig_kprobe_multi_all;
> > +extern const struct bench bench_trig_kretprobe_multi_all;
> > extern const struct bench bench_trig_fexit;
> > extern const struct bench bench_trig_fmodret;
> > extern const struct bench bench_trig_tp;
> > @@ -578,6 +580,8 @@ static const struct bench *benchs[] = {
> > &bench_trig_kprobe_multi,
> > &bench_trig_kretprobe_multi,
> > &bench_trig_fentry,
> > + &bench_trig_kprobe_multi_all,
> > + &bench_trig_kretprobe_multi_all,
> > &bench_trig_fexit,
> > &bench_trig_fmodret,
> > &bench_trig_tp,
> > diff --git a/tools/testing/selftests/bpf/benchs/bench_trigger.c b/tools/testing/selftests/bpf/benchs/bench_trigger.c
> > index 82327657846e..c6634a64a7c0 100644
> > --- a/tools/testing/selftests/bpf/benchs/bench_trigger.c
> > +++ b/tools/testing/selftests/bpf/benchs/bench_trigger.c
> > @@ -226,6 +226,58 @@ static void trigger_fentry_setup(void)
> > attach_bpf(ctx.skel->progs.bench_trigger_fentry);
> > }
> >
> > +static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe)
> > +{
> > + LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
> > + char **syms = NULL;
> > + size_t cnt = 0;
> > +
> > + if (bpf_get_ksyms(&syms, &cnt, true)) {
> > + printf("failed to get ksyms\n");
>
> we seem to be using fprintf(stderr, "...") for emitting errors like
> this (at least in some benchmarks, and it makes sense to me). Do the
> same?
OK!
>
> > + exit(1);
> > + }
> > +
> > + printf("found %zu ksyms\n", cnt);
>
> stray debug output?
OK!
Thanks!
Menglong Dong
>
> > + opts.syms = (const char **) syms;
> > + opts.cnt = cnt;
> > + opts.retprobe = kretprobe;
> > + /* attach empty to all the kernel functions except bpf_get_numa_node_id. */
> > + if (!bpf_program__attach_kprobe_multi_opts(empty, NULL, &opts)) {
> > + printf("failed to attach bpf_program__attach_kprobe_multi_opts to all\n");
> > + exit(1);
> > + }
> > +}
> > +
>
> [...]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-08-21 1:40 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-19 3:39 [PATCH bpf-next 0/3] selftests/bpf: benchmark all symbols for kprobe-multi Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 1/3] selftests/bpf: move get_ksyms and get_addrs to trace_helpers.c Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 2/3] selftests/bpf: skip recursive functions for kprobe_multi Menglong Dong
2025-08-20 22:47 ` Andrii Nakryiko
2025-08-21 1:39 ` Menglong Dong
2025-08-19 3:39 ` [PATCH bpf-next 3/3] selftests/bpf: add benchmark testing for kprobe-multi-all Menglong Dong
2025-08-20 22:53 ` Andrii Nakryiko
2025-08-21 1:40 ` Menglong Dong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).