Skip to content

Commit 6302bde

Browse files
Yonghong SongAlexei Starovoitov
authored andcommitted
selftests/bpf: Add a kprobe_multi subtest to use addrs instead of syms
Get addrs directly from available_filter_functions_addrs and send to the kernel during kprobe_multi_attach. This avoids consultation of /proc/kallsyms. But available_filter_functions_addrs is introduced in 6.5, i.e., it is introduced recently, so I skip the test if the kernel does not support it. Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Link: https://lore.kernel.org/r/20240326041523.1200301-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 9edaafa commit 6302bde

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,69 @@ static int get_syms(char ***symsp, size_t *cntp, bool kernel)
477477
return err;
478478
}
479479

480+
static int get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel)
481+
{
482+
unsigned long *addr, *addrs, *tmp_addrs;
483+
int err = 0, max_cnt, inc_cnt;
484+
char *name = NULL;
485+
size_t cnt = 0;
486+
char buf[256];
487+
FILE *f;
488+
489+
if (access("/sys/kernel/tracing/trace", F_OK) == 0)
490+
f = fopen("/sys/kernel/tracing/available_filter_functions_addrs", "r");
491+
else
492+
f = fopen("/sys/kernel/debug/tracing/available_filter_functions_addrs", "r");
493+
494+
if (!f)
495+
return -ENOENT;
496+
497+
/* In my local setup, the number of entries is 50k+ so Let us initially
498+
* allocate space to hold 64k entries. If 64k is not enough, incrementally
499+
* increase 1k each time.
500+
*/
501+
max_cnt = 65536;
502+
inc_cnt = 1024;
503+
addrs = malloc(max_cnt * sizeof(long));
504+
if (addrs == NULL) {
505+
err = -ENOMEM;
506+
goto error;
507+
}
508+
509+
while (fgets(buf, sizeof(buf), f)) {
510+
if (is_invalid_entry(buf, kernel))
511+
continue;
512+
513+
free(name);
514+
if (sscanf(buf, "%p %ms$*[^\n]\n", &addr, &name) != 2)
515+
continue;
516+
if (skip_entry(name))
517+
continue;
518+
519+
if (cnt == max_cnt) {
520+
max_cnt += inc_cnt;
521+
tmp_addrs = realloc(addrs, max_cnt);
522+
if (!tmp_addrs) {
523+
err = -ENOMEM;
524+
goto error;
525+
}
526+
addrs = tmp_addrs;
527+
}
528+
529+
addrs[cnt++] = (unsigned long)addr;
530+
}
531+
532+
*addrsp = addrs;
533+
*cntp = cnt;
534+
535+
error:
536+
free(name);
537+
fclose(f);
538+
if (err)
539+
free(addrs);
540+
return err;
541+
}
542+
480543
static void do_bench_test(struct kprobe_multi_empty *skel, struct bpf_kprobe_multi_opts *opts)
481544
{
482545
long attach_start_ns, attach_end_ns;
@@ -529,6 +592,37 @@ static void test_kprobe_multi_bench_attach(bool kernel)
529592
free(syms);
530593
}
531594

595+
static void test_kprobe_multi_bench_attach_addr(bool kernel)
596+
{
597+
LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
598+
struct kprobe_multi_empty *skel = NULL;
599+
unsigned long *addrs = NULL;
600+
size_t cnt = 0;
601+
int err;
602+
603+
err = get_addrs(&addrs, &cnt, kernel);
604+
if (err == -ENOENT) {
605+
test__skip();
606+
return;
607+
}
608+
609+
if (!ASSERT_OK(err, "get_addrs"))
610+
return;
611+
612+
skel = kprobe_multi_empty__open_and_load();
613+
if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
614+
goto cleanup;
615+
616+
opts.addrs = addrs;
617+
opts.cnt = cnt;
618+
619+
do_bench_test(skel, &opts);
620+
621+
cleanup:
622+
kprobe_multi_empty__destroy(skel);
623+
free(addrs);
624+
}
625+
532626
static void test_attach_override(void)
533627
{
534628
struct kprobe_multi_override *skel = NULL;
@@ -569,6 +663,10 @@ void serial_test_kprobe_multi_bench_attach(void)
569663
test_kprobe_multi_bench_attach(true);
570664
if (test__start_subtest("modules"))
571665
test_kprobe_multi_bench_attach(false);
666+
if (test__start_subtest("kernel"))
667+
test_kprobe_multi_bench_attach_addr(true);
668+
if (test__start_subtest("modules"))
669+
test_kprobe_multi_bench_attach_addr(false);
572670
}
573671

574672
void test_kprobe_multi_test(void)

0 commit comments

Comments
 (0)