diff options
author | Alexei Starovoitov <ast@kernel.org> | 2025-01-06 21:59:50 +0300 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2025-01-06 21:59:56 +0300 |
commit | 859a7db4c7db84b06ca7fc9c60eb45a130c8fbec (patch) | |
tree | ed16b336308fe7e06470331a87eb492bfd7c9de0 /tools | |
parent | 2532608530eab68207e384053fae7db7f35256ee (diff) | |
parent | 87091dd986db51406e64dd5e8c9d22617c66c6af (diff) | |
download | linux-859a7db4c7db84b06ca7fc9c60eb45a130c8fbec.tar.xz |
Merge branch 'bpf-allow-bpf_for-bpf_repeat-while-holding-spin'
Emil Tsalapatis says:
====================
In BPF programs, kfunc calls while holding a lock are not allowed
because kfuncs may sleep by default. The exception to this rule are the
functions in special_kfunc_list, which are guaranteed to not sleep. The
bpf_iter_num_* functions used by the bpf_for and bpf_repeat macros make
no function calls themselves, and as such are guaranteed to not sleep.
Add them to special_kfunc_list to allow them within BPF spinlock
critical sections.
Signed-off-by: Emil Tsalapatis (Meta) <emil@etsalapatis.com>
====================
Link: https://patch.msgid.link/20250104202528.882482-1-emil@etsalapatis.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/bpf/progs/verifier_spin_lock.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/progs/verifier_spin_lock.c b/tools/testing/selftests/bpf/progs/verifier_spin_lock.c index 25599eac9a70..d9d7b05cf6d2 100644 --- a/tools/testing/selftests/bpf/progs/verifier_spin_lock.c +++ b/tools/testing/selftests/bpf/progs/verifier_spin_lock.c @@ -530,4 +530,30 @@ l1_%=: exit; \ : __clobber_all); } +SEC("tc") +__description("spin_lock: loop within a locked region") +__success __failure_unpriv __msg_unpriv("") +__retval(0) +int bpf_loop_inside_locked_region(void) +{ + const int zero = 0; + struct val *val; + int i, j = 0; + + val = bpf_map_lookup_elem(&map_spin_lock, &zero); + if (!val) + return -1; + + bpf_spin_lock(&val->l); + bpf_for(i, 0, 10) { + j++; + /* Silence "unused variable" warnings. */ + if (j == 10) + break; + } + bpf_spin_unlock(&val->l); + + return 0; +} + char _license[] SEC("license") = "GPL"; |