bpf: Remove in_atomic() from bpf_link_put().
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Wed, 14 Jun 2023 08:34:30 +0000 (10:34 +0200)
committerAndrii Nakryiko <andrii@kernel.org>
Fri, 16 Jun 2023 16:28:02 +0000 (09:28 -0700)
commitab5d47bd41b1db82c295b0e751e2b822b43a4b5a
treec66e8b8acfee15b488333818f13e913544c62b28
parentc03531e087b550d975bc1eb32f56f9da47aaa77e
bpf: Remove in_atomic() from bpf_link_put().

bpf_free_inode() is invoked as a RCU callback. Usually RCU callbacks are
invoked within softirq context. By setting rcutree.use_softirq=0 boot
option the RCU callbacks will be invoked in a per-CPU kthread with
bottom halves disabled which implies a RCU read section.

On PREEMPT_RT the context remains fully preemptible. The RCU read
section however does not allow schedule() invocation. The latter happens
in mutex_lock() performed by bpf_trampoline_unlink_prog() originated
from bpf_link_put().

It was pointed out that the bpf_link_put() invocation should not be
delayed if originated from close(). It was also pointed out that other
invocations from within a syscall should also avoid the workqueue.
Everyone else should use workqueue by default to remain safe in the
future (while auditing the code, every caller was preemptible except for
the RCU case).

Let bpf_link_put() use the worker unconditionally. Add
bpf_link_put_direct() which will directly free the resources and is used
by close() and from within __sys_bpf().

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20230614083430.oENawF8f@linutronix.de
kernel/bpf/syscall.c