mirror of
https://github.com/OpenVoiceOS/OpenVoiceOS
synced 2025-02-23 07:07:39 +01:00
120 lines
3.6 KiB
Diff
120 lines
3.6 KiB
Diff
From 88ec5664a42344c84c246d13dd726a4cbe2d9e8d Mon Sep 17 00:00:00 2001
|
|
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
Date: Wed, 14 Jun 2023 10:34:30 +0200
|
|
Subject: [PATCH 59/62] 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
|
|
(cherry picked from commit ab5d47bd41b1db82c295b0e751e2b822b43a4b5a)
|
|
Signed-off-by: Clark Williams <clark.williams@gmail.com>
|
|
---
|
|
kernel/bpf/syscall.c | 29 ++++++++++++++++-------------
|
|
1 file changed, 16 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
|
|
index c0915e2424f1..f8ba6e0a5c08 100644
|
|
--- a/kernel/bpf/syscall.c
|
|
+++ b/kernel/bpf/syscall.c
|
|
@@ -2732,28 +2732,31 @@ static void bpf_link_put_deferred(struct work_struct *work)
|
|
bpf_link_free(link);
|
|
}
|
|
|
|
-/* bpf_link_put can be called from atomic context, but ensures that resources
|
|
- * are freed from process context
|
|
+/* bpf_link_put might be called from atomic context. It needs to be called
|
|
+ * from sleepable context in order to acquire sleeping locks during the process.
|
|
*/
|
|
void bpf_link_put(struct bpf_link *link)
|
|
{
|
|
if (!atomic64_dec_and_test(&link->refcnt))
|
|
return;
|
|
|
|
- if (in_atomic()) {
|
|
- INIT_WORK(&link->work, bpf_link_put_deferred);
|
|
- schedule_work(&link->work);
|
|
- } else {
|
|
- bpf_link_free(link);
|
|
- }
|
|
+ INIT_WORK(&link->work, bpf_link_put_deferred);
|
|
+ schedule_work(&link->work);
|
|
}
|
|
EXPORT_SYMBOL(bpf_link_put);
|
|
|
|
+static void bpf_link_put_direct(struct bpf_link *link)
|
|
+{
|
|
+ if (!atomic64_dec_and_test(&link->refcnt))
|
|
+ return;
|
|
+ bpf_link_free(link);
|
|
+}
|
|
+
|
|
static int bpf_link_release(struct inode *inode, struct file *filp)
|
|
{
|
|
struct bpf_link *link = filp->private_data;
|
|
|
|
- bpf_link_put(link);
|
|
+ bpf_link_put_direct(link);
|
|
return 0;
|
|
}
|
|
|
|
@@ -4674,7 +4677,7 @@ static int link_update(union bpf_attr *attr)
|
|
if (ret)
|
|
bpf_prog_put(new_prog);
|
|
out_put_link:
|
|
- bpf_link_put(link);
|
|
+ bpf_link_put_direct(link);
|
|
return ret;
|
|
}
|
|
|
|
@@ -4697,7 +4700,7 @@ static int link_detach(union bpf_attr *attr)
|
|
else
|
|
ret = -EOPNOTSUPP;
|
|
|
|
- bpf_link_put(link);
|
|
+ bpf_link_put_direct(link);
|
|
return ret;
|
|
}
|
|
|
|
@@ -4767,7 +4770,7 @@ static int bpf_link_get_fd_by_id(const union bpf_attr *attr)
|
|
|
|
fd = bpf_link_new_fd(link);
|
|
if (fd < 0)
|
|
- bpf_link_put(link);
|
|
+ bpf_link_put_direct(link);
|
|
|
|
return fd;
|
|
}
|
|
@@ -4844,7 +4847,7 @@ static int bpf_iter_create(union bpf_attr *attr)
|
|
return PTR_ERR(link);
|
|
|
|
err = bpf_iter_new_fd(link);
|
|
- bpf_link_put(link);
|
|
+ bpf_link_put_direct(link);
|
|
|
|
return err;
|
|
}
|
|
--
|
|
2.43.0
|
|
|