On Thu, Mar 19, 2026 at 12:03:37PM +0800, Sun Jian wrote:
> 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. 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 -t modify_return -vv
>   ./test_progs -t get_func_ip_test -vv
>   ./test_progs -t get_func_args_test -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,\
> kprobe_multi_test -vv
>   20 runs of:
>     ./test_progs -j$(nproc) -t
>     trampoline_count,modify_return,get_func_ip_test,get_func_args_test,\
> kprobe_multi_test
> 
> Signed-off-by: Sun Jian <[email protected]>
> ---
> 
> v2:
> - rewrite the subject to describe the change
> - resend with the correct patch content
> - resend as a reply to v1
> 
>  .../selftests/bpf/prog_tests/trampoline_count.c |  3 +--
>  .../selftests/bpf/progs/test_trampoline_count.c |  6 +++---
>  .../selftests/bpf/test_kmods/bpf_testmod.c      | 17 +++++++++++++++++
>  3 files changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/trampoline_count.c 
> b/tools/testing/selftests/bpf/prog_tests/trampoline_count.c
> index 6cd7349d4a2b..b19358aed126 100644
> --- a/tools/testing/selftests/bpf/prog_tests/trampoline_count.c
> +++ b/tools/testing/selftests/bpf/prog_tests/trampoline_count.c
> @@ -30,8 +30,7 @@ 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" };
> diff --git a/tools/testing/selftests/bpf/progs/test_trampoline_count.c 
> b/tools/testing/selftests/bpf/progs/test_trampoline_count.c
> index 7765720da7d5..14ad2f53cf33 100644
> --- a/tools/testing/selftests/bpf/progs/test_trampoline_count.c
> +++ b/tools/testing/selftests/bpf/progs/test_trampoline_count.c
> @@ -3,19 +3,19 @@
>  #include <bpf/bpf_helpers.h>
>  #include <bpf/bpf_tracing.h>
>  
> -SEC("fentry/bpf_modify_return_test")
> +SEC("fentry/bpf_testmod_trampoline_count_test")
>  int BPF_PROG(fentry_test, int a, int *b)
>  {
>       return 0;
>  }
>  
> -SEC("fmod_ret/bpf_modify_return_test")
> +SEC("fmod_ret/bpf_testmod_trampoline_count_test")
>  int BPF_PROG(fmod_ret_test, int a, int *b, int ret)
>  {
>       return 0;
>  }
>  
> -SEC("fexit/bpf_modify_return_test")
> +SEC("fexit/bpf_testmod_trampoline_count_test")
>  int BPF_PROG(fexit_test, int a, int *b, int ret)

last part of the trampoline_count test executes the probe through the
kernel's test_run which executes bpf_modify_return_test

I don't think it changes much because the programs are doing nothing
I guess it's there just to make sure the link failure did not screw
up anything

we could call bpf_testmod_trampoline_count_test from
bpf_testmod_test_read and have the test to call
trigger_module_test_read

jirka


>  {
>       return 0;
> diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c 
> b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
> index e62c6b78657f..6eaceb4dfbec 100644
> --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
> +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
> @@ -581,6 +581,12 @@ noinline int bpf_fentry_shadow_test(int a)
>  }
>  EXPORT_SYMBOL_GPL(bpf_fentry_shadow_test);
>  
> +noinline int bpf_testmod_trampoline_count_test(int a, int *b)
> +{
> +     *b += 1;
> +     return a + *b;
> +}
> +
>  __bpf_hook_end();
>  
>  static struct bin_attribute bin_attr_bpf_testmod_file __ro_after_init = {
> @@ -1843,6 +1849,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[] = {
> @@ -1859,6 +1875,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);
> 
> base-commit: 8a30aeb0d1b4e4aaf7f7bae72f20f2ae75385ccb
> -- 
> 2.43.0
> 

Reply via email to