diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:59 +0000 |
commit | 01997497f915e8f79871f3f2acb55ac465051d24 (patch) | |
tree | 1ce1afd7246e1014199e15cbf854bf7924458e5d /debian/patches-rt/0059-bpf-Remove-in_atomic-from-bpf_link_put.patch | |
parent | Adding upstream version 6.1.76. (diff) | |
download | linux-01997497f915e8f79871f3f2acb55ac465051d24.tar.xz linux-01997497f915e8f79871f3f2acb55ac465051d24.zip |
Adding debian version 6.1.76-1.debian/6.1.76-1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches-rt/0059-bpf-Remove-in_atomic-from-bpf_link_put.patch')
-rw-r--r-- | debian/patches-rt/0059-bpf-Remove-in_atomic-from-bpf_link_put.patch | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/debian/patches-rt/0059-bpf-Remove-in_atomic-from-bpf_link_put.patch b/debian/patches-rt/0059-bpf-Remove-in_atomic-from-bpf_link_put.patch new file mode 100644 index 000000000..8abf764af --- /dev/null +++ b/debian/patches-rt/0059-bpf-Remove-in_atomic-from-bpf_link_put.patch @@ -0,0 +1,120 @@ +From 05999b640eb04be872e5491a040701fcddc73349 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(). +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.1/older/patches-6.1.69-rt21.tar.xz + +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 + |