When rollbacking, the prepared trampolines should be reverted. In this test, the first bpf prog will be attached with the trampoline, and the second bpf prog won't be attached because the bpf prog has been attached by a fentry.multi prog, that causes the rollback procedure. Assisted-by: Codex:gpt-5.5 Signed-off-by: Leon Hwang --- .../selftests/bpf/prog_tests/tracing_multi.c | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_multi.c b/tools/testing/selftests/bpf/prog_tests/tracing_multi.c index bcf933760bc5..dfa24e229ff7 100644 --- a/tools/testing/selftests/bpf/prog_tests/tracing_multi.c +++ b/tools/testing/selftests/bpf/prog_tests/tracing_multi.c @@ -1308,6 +1308,67 @@ static void test_attach_api_bpf_prog_fails(void) free(ids); } +static void test_rollback_bpf_prog(void) +{ + int token_fd, prog_fd, fd = -1, pre_fd = -1; + LIBBPF_OPTS(bpf_link_create_opts, lopts); + struct tracing_multi_bpf *skel = NULL; + __u32 target_ids[2], ids[2]; + int target_fds[2], fds[2]; + struct bpf_program *prog; + int first, second; + + skel = tracing_multi_bpf__open_and_load(); + if (!ASSERT_OK_PTR(skel, "tracing_multi_bpf__open_and_load")) + return; + + token_fd = bpf_object__token_fd(skel->obj); + token_fd = token_fd < 0 ? 0 : token_fd; + target_fds[0] = bpf_program__fd(skel->progs.target_1); + target_fds[1] = bpf_program__fd(skel->progs.target_2); + target_ids[0] = libbpf_find_prog_btf_id("target_1", target_fds[0], token_fd); + if (!ASSERT_GT(target_ids[0], 0, "target_1_btf_id")) + goto cleanup; + target_ids[1] = libbpf_find_prog_btf_id("target_2", target_fds[1], token_fd); + if (!ASSERT_GT(target_ids[1], 0, "target_2_btf_id")) + goto cleanup; + + first = target_fds[0] < target_fds[1] ? 0 : 1; + second = 1 - first; + fds[0] = target_fds[first]; + fds[1] = target_fds[second]; + ids[0] = target_ids[first]; + ids[1] = target_ids[second]; + + prog_fd = bpf_program__fd(skel->progs.test_fentry); + lopts.tracing_multi.ids = &ids[1]; + lopts.tracing_multi.fds = &fds[1]; + lopts.tracing_multi.cnt = 1; + pre_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_FENTRY_MULTI, &lopts); + if (!ASSERT_GE(pre_fd, 0, "pre_attach")) + goto cleanup; + + lopts.tracing_multi.ids = ids; + lopts.tracing_multi.fds = fds; + lopts.tracing_multi.cnt = ARRAY_SIZE(ids); + + fd = bpf_link_create(prog_fd, 0, BPF_TRACE_FENTRY_MULTI, &lopts); + if (!ASSERT_EQ(fd, -EBUSY, "bpf_link_create")) + goto cleanup; + + prog = first == 0 ? skel->progs.target_1 : skel->progs.target_2; + if (run_bpf_target(prog, first + 1, "rollback_target")) + goto cleanup; + ASSERT_EQ(skel->bss->test_result_fentry, 0, "test_result_fentry"); + +cleanup: + if (fd >= 0) + close(fd); + if (pre_fd >= 0) + close(pre_fd); + tracing_multi_bpf__destroy(skel); +} + void test_tracing_multi_prog_test(void) { if (test__start_subtest("link_api")) @@ -1316,4 +1377,6 @@ void test_tracing_multi_prog_test(void) test_attach_api_bpf_prog_fails(); if (test__start_subtest("cookies")) test_link_api_bpf_prog(true); + if (test__start_subtest("rollback")) + test_rollback_bpf_prog(); } -- 2.55.0