]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/bpf: move trampoline_count to dedicated bpf_testmod target
authorSun Jian <sun.jian.kdev@gmail.com>
Tue, 24 Mar 2026 04:49:49 +0000 (12:49 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 24 Mar 2026 20:39:32 +0000 (13:39 -0700)
trampoline_count fills all trampoline attachment slots for a single
target function and verifies that one extra attach fails with -E2BIG.

It currently targets bpf_modify_return_test, which is also used by
other selftests such as modify_return, get_func_ip_test, and
get_func_args_test. When such tests run in parallel, they can contend
for the same per-function trampoline quota and cause unexpected attach
failures. This issue is currently masked by harness serialization.

Move trampoline_count to a dedicated bpf_testmod target and register it
for fmod_ret attachment. Also route the final trigger through
trigger_module_test_read(), so the execution path exercises the same
dedicated target.

This keeps the test semantics unchanged while isolating it from other
selftests, so it no longer needs to run in serial mode. Remove the
TODO comment as well.

Tested:
  ./test_progs -t trampoline_count -vv
  ./test_progs -j$(nproc) -t trampoline_count -vv
  ./test_progs -j$(nproc) -t \
    trampoline_count,modify_return,get_func_ip_test,get_func_args_test -vv
  20 runs of:
    ./test_progs -j$(nproc) -t \
      trampoline_count,modify_return,get_func_ip_test,get_func_args_test

Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20260324044949.869801-1-sun.jian.kdev@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/trampoline_count.c
tools/testing/selftests/bpf/progs/test_trampoline_count.c
tools/testing/selftests/bpf/test_kmods/bpf_testmod.c

index 6cd7349d4a2bac2627d3fcee589374e8831768c8..7321850db75f4176c1b5922d5d025fe8b96f5e0f 100644 (file)
@@ -30,16 +30,14 @@ static struct bpf_program *load_prog(char *file, char *name, struct inst *inst)
        return prog;
 }
 
-/* TODO: use different target function to run in concurrent mode */
-void serial_test_trampoline_count(void)
+void test_trampoline_count(void)
 {
        char *file = "test_trampoline_count.bpf.o";
        char *const progs[] = { "fentry_test", "fmod_ret_test", "fexit_test" };
-       int bpf_max_tramp_links, err, i, prog_fd;
+       int bpf_max_tramp_links, i;
        struct bpf_program *prog;
        struct bpf_link *link;
        struct inst *inst;
-       LIBBPF_OPTS(bpf_test_run_opts, opts);
 
        bpf_max_tramp_links = get_bpf_max_tramp_links();
        if (!ASSERT_GE(bpf_max_tramp_links, 1, "bpf_max_tramp_links"))
@@ -80,16 +78,7 @@ void serial_test_trampoline_count(void)
                goto cleanup;
 
        /* and finally execute the probe */
-       prog_fd = bpf_program__fd(prog);
-       if (!ASSERT_GE(prog_fd, 0, "bpf_program__fd"))
-               goto cleanup;
-
-       err = bpf_prog_test_run_opts(prog_fd, &opts);
-       if (!ASSERT_OK(err, "bpf_prog_test_run_opts"))
-               goto cleanup;
-
-       ASSERT_EQ(opts.retval & 0xffff, 33, "bpf_modify_return_test.result");
-       ASSERT_EQ(opts.retval >> 16, 2, "bpf_modify_return_test.side_effect");
+       ASSERT_OK(trigger_module_test_read(256), "trigger_module_test_read");
 
 cleanup:
        for (; i >= 0; i--) {
index 7765720da7d5830a6cfd042242eeb648ef72932b..02f52806b1b2dbd882e56740f4e393272c0856de 100644 (file)
@@ -3,20 +3,20 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 
-SEC("fentry/bpf_modify_return_test")
-int BPF_PROG(fentry_test, int a, int *b)
+SEC("fentry/bpf_testmod_trampoline_count_test")
+int BPF_PROG(fentry_test)
 {
        return 0;
 }
 
-SEC("fmod_ret/bpf_modify_return_test")
-int BPF_PROG(fmod_ret_test, int a, int *b, int ret)
+SEC("fmod_ret/bpf_testmod_trampoline_count_test")
+int BPF_PROG(fmod_ret_test, int ret)
 {
        return 0;
 }
 
-SEC("fexit/bpf_modify_return_test")
-int BPF_PROG(fexit_test, int a, int *b, int ret)
+SEC("fexit/bpf_testmod_trampoline_count_test")
+int BPF_PROG(fexit_test, int ret)
 {
        return 0;
 }
index 297b02372fa6e05b50a1a84a63f29f87f157aec3..061356f10093d35e5f6a89074d6c67e1a074e3fc 100644 (file)
@@ -470,6 +470,11 @@ noinline void bpf_testmod_stacktrace_test_1(void)
 
 int bpf_testmod_fentry_ok;
 
+noinline int bpf_testmod_trampoline_count_test(void)
+{
+       return 0;
+}
+
 noinline ssize_t
 bpf_testmod_test_read(struct file *file, struct kobject *kobj,
                      const struct bin_attribute *bin_attr,
@@ -548,6 +553,8 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
                        21, 22, 23, 24, 25, 26) != 231)
                goto out;
 
+       bpf_testmod_trampoline_count_test();
+
        bpf_testmod_stacktrace_test_1();
 
        bpf_testmod_fentry_ok = 1;
@@ -1902,6 +1909,16 @@ struct bpf_struct_ops testmod_multi_st_ops = {
 
 extern int bpf_fentry_test1(int a);
 
+BTF_KFUNCS_START(bpf_testmod_trampoline_count_ids)
+BTF_ID_FLAGS(func, bpf_testmod_trampoline_count_test)
+BTF_KFUNCS_END(bpf_testmod_trampoline_count_ids)
+
+static const struct
+btf_kfunc_id_set bpf_testmod_trampoline_count_fmodret_set = {
+       .owner = THIS_MODULE,
+       .set = &bpf_testmod_trampoline_count_ids,
+};
+
 static int bpf_testmod_init(void)
 {
        const struct btf_id_dtor_kfunc bpf_testmod_dtors[] = {
@@ -1918,6 +1935,7 @@ static int bpf_testmod_init(void)
        ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_testmod_kfunc_set);
        ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &bpf_testmod_kfunc_set);
        ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &bpf_testmod_kfunc_set);
+       ret = ret ?: register_btf_fmodret_id_set(&bpf_testmod_trampoline_count_fmodret_set);
        ret = ret ?: register_bpf_struct_ops(&bpf_bpf_testmod_ops, bpf_testmod_ops);
        ret = ret ?: register_bpf_struct_ops(&bpf_testmod_ops2, bpf_testmod_ops2);
        ret = ret ?: register_bpf_struct_ops(&bpf_testmod_ops3, bpf_testmod_ops3);