On Mon, Dec 11, 2023 at 07:28:43PM +0800, Hou Tao wrote: > From: Hou Tao <houtao1@xxxxxxxxxx> > > If an abnormally huge cnt is used for multi-uprobes attachment, the > following warning will be reported: > > ------------[ cut here ]------------ > WARNING: CPU: 7 PID: 406 at mm/util.c:632 kvmalloc_node+0xd9/0xe0 > Modules linked in: bpf_testmod(O) > CPU: 7 PID: 406 Comm: test_progs Tainted: G ...... 6.7.0-rc3+ #32 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) ...... > RIP: 0010:kvmalloc_node+0xd9/0xe0 > ...... > Call Trace: > <TASK> > ? __warn+0x89/0x150 > ? kvmalloc_node+0xd9/0xe0 > bpf_uprobe_multi_link_attach+0x14a/0x480 > __sys_bpf+0x14a9/0x2bc0 > do_syscall_64+0x36/0xb0 > entry_SYSCALL_64_after_hwframe+0x6e/0x76 > ...... > </TASK> > ---[ end trace 0000000000000000 ]--- > > So add a test to ensure the warning is fixed. > > Signed-off-by: Hou Tao <houtao1@xxxxxxxxxx> > --- > .../bpf/prog_tests/uprobe_multi_test.c | 43 ++++++++++++++++++- > 1 file changed, 42 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c > index ece260cf2c0b..379ee9cc6221 100644 > --- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c > +++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c > @@ -234,6 +234,45 @@ static void test_attach_api_syms(void) > test_attach_api("/proc/self/exe", NULL, &opts); > } > > +static void test_failed_link_api(void) > +{ > + LIBBPF_OPTS(bpf_link_create_opts, opts); > + const char *path = "/proc/self/exe"; > + struct uprobe_multi *skel = NULL; > + unsigned long *offsets = NULL; > + const char *syms[3] = { > + "uprobe_multi_func_1", > + "uprobe_multi_func_2", > + "uprobe_multi_func_3", > + }; > + int link_fd = -1, err; > + > + err = elf_resolve_syms_offsets(path, 3, syms, (unsigned long **) &offsets, STT_FUNC); > + if (!ASSERT_OK(err, "elf_resolve_syms_offsets")) > + return; we should not need any symbols/offset for this tests right? the allocation takes place before the offsets are checked, so I think using just some pointer != NULL should be enough? thanks, jirka > + > + skel = uprobe_multi__open_and_load(); > + if (!ASSERT_OK_PTR(skel, "uprobe_multi__open_and_load")) > + goto cleanup; > + > + /* abnormal cnt */ > + opts.uprobe_multi.path = path; > + opts.uprobe_multi.offsets = offsets; > + opts.uprobe_multi.cnt = INT_MAX; > + opts.kprobe_multi.flags = 0; > + link_fd = bpf_link_create(bpf_program__fd(skel->progs.uprobe), 0, > + BPF_TRACE_UPROBE_MULTI, &opts); > + if (!ASSERT_ERR(link_fd, "link_fd")) > + goto cleanup; > + if (!ASSERT_EQ(link_fd, -ENOMEM, "no mem fail")) > + goto cleanup; > +cleanup: > + if (link_fd >= 0) > + close(link_fd); > + uprobe_multi__destroy(skel); > + free(offsets); > +} > + > static void __test_link_api(struct child *child) > { > int prog_fd, link1_fd = -1, link2_fd = -1, link3_fd = -1, link4_fd = -1; > @@ -311,7 +350,7 @@ static void __test_link_api(struct child *child) > free(offsets); > } > > -void test_link_api(void) > +static void test_link_api(void) > { > struct child *child; > > @@ -408,6 +447,8 @@ void test_uprobe_multi_test(void) > test_attach_api_syms(); > if (test__start_subtest("link_api")) > test_link_api(); > + if (test__start_subtest("failed_link_api")) > + test_failed_link_api(); > if (test__start_subtest("bench_uprobe")) > test_bench_attach_uprobe(); > if (test__start_subtest("bench_usdt")) > -- > 2.29.2 >