diff options
| author | Qiliang Yuan <odys.yuan@gmail.com> | 2026-10-22 16:48:36 +0800 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-10-24 03:48:42 +0000 |
| commit | 232475c32994411bd816d6358ca48e94010fc84a (patch) | |
| tree | 31be17faf09261f309bf2358645a60ec36aeaea1 /include/linux | |
| parent | 17bb0e2f6c8043f70a693a5f3797471cbed354c8 (diff) | |
bpf: Protect the struct_ops association with a spinlock
bpf_prog_assoc_struct_ops() and bpf_prog_disassoc_struct_ops() update
prog->aux->st_ops_assoc under st_ops_assoc_mutex, and the latter puts
the map of a non-struct_ops prog while holding it.
A struct_ops map is about to dissociate its progs from
map_free_pre_rcu(), which bpf_map_put() calls in whatever context drops
the last reference, including softirq, e.g. bpf_struct_ops_put() from
tcp_cleanup_congestion_control(). A mutex can't be taken there, and the
put of the last reference under the lock of one prog would take the
lock of other progs.
Replace the mutex with a spinlock taken with interrupts disabled, and
put the map after dropping it.
Signed-off-by: Qiliang Yuan <odys.yuan@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261022-selftests-bpf-struct-ops-assoc-timer-v6-1-2c0f18e82582@gmail.com
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/bpf.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 580f89c450b5..17b2a425e05e 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1979,7 +1979,7 @@ struct bpf_prog_aux { struct rcu_work rwork; }; struct bpf_stream *stream[2]; - struct mutex st_ops_assoc_mutex; + spinlock_t st_ops_assoc_lock; /* protects st_ops_assoc */ struct bpf_map __rcu *st_ops_assoc; }; |
