From: Andrii Nakryiko <andrii@kernel.org>
To: linux-trace-kernel@vger.kernel.org, peterz@infradead.org,
oleg@redhat.com
Cc: rostedt@goodmis.org, mhiramat@kernel.org, bpf@vger.kernel.org,
linux-kernel@vger.kernel.org, jolsa@kernel.org,
paulmck@kernel.org, Andrii Nakryiko <andrii@kernel.org>
Subject: [PATCH 1/3] uprobes: allow put_uprobe() from non-sleepable softirq context
Date: Mon, 9 Sep 2024 15:49:01 -0700 [thread overview]
Message-ID: <20240909224903.3498207-2-andrii@kernel.org> (raw)
In-Reply-To: <20240909224903.3498207-1-andrii@kernel.org>
Currently put_uprobe() might trigger mutex_lock()/mutex_unlock(), which
makes it unsuitable to be called from more restricted context like softirq.
Let's make put_uprobe() agnostic to the context in which it is called,
and use work queue to defer the mutex-protected clean up steps.
To avoid unnecessarily increasing the size of struct uprobe, we colocate
work_struct in parallel with rb_node and rcu, both of which are unused
by the time we get to schedule clean up work.
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
kernel/events/uprobes.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index a2e6a57f79f2..377bd524bc8b 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -27,6 +27,7 @@
#include <linux/shmem_fs.h>
#include <linux/khugepaged.h>
#include <linux/rcupdate_trace.h>
+#include <linux/workqueue.h>
#include <linux/uprobes.h>
@@ -54,14 +55,20 @@ DEFINE_STATIC_PERCPU_RWSEM(dup_mmap_sem);
#define UPROBE_COPY_INSN 0
struct uprobe {
- struct rb_node rb_node; /* node in the rb tree */
+ union {
+ struct {
+ struct rb_node rb_node; /* node in the rb tree */
+ struct rcu_head rcu;
+ };
+ /* work is used only during freeing, rcu and rb_node are unused at that point */
+ struct work_struct work;
+ };
refcount_t ref;
struct rw_semaphore register_rwsem;
struct rw_semaphore consumer_rwsem;
struct list_head pending_list;
struct list_head consumers;
struct inode *inode; /* Also hold a ref to inode */
- struct rcu_head rcu;
loff_t offset;
loff_t ref_ctr_offset;
unsigned long flags;
@@ -620,11 +627,28 @@ static inline bool uprobe_is_active(struct uprobe *uprobe)
return !RB_EMPTY_NODE(&uprobe->rb_node);
}
+static void uprobe_free_deferred(struct work_struct *work)
+{
+ struct uprobe *uprobe = container_of(work, struct uprobe, work);
+
+ /*
+ * If application munmap(exec_vma) before uprobe_unregister()
+ * gets called, we don't get a chance to remove uprobe from
+ * delayed_uprobe_list from remove_breakpoint(). Do it here.
+ */
+ mutex_lock(&delayed_uprobe_lock);
+ delayed_uprobe_remove(uprobe, NULL);
+ mutex_unlock(&delayed_uprobe_lock);
+
+ kfree(uprobe);
+}
+
static void uprobe_free_rcu(struct rcu_head *rcu)
{
struct uprobe *uprobe = container_of(rcu, struct uprobe, rcu);
- kfree(uprobe);
+ INIT_WORK(&uprobe->work, uprobe_free_deferred);
+ schedule_work(&uprobe->work);
}
static void put_uprobe(struct uprobe *uprobe)
--
2.43.5
next prev parent reply other threads:[~2024-09-09 22:49 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-09 22:49 [PATCH 0/3] SRCU-protected uretprobes hot path Andrii Nakryiko
2024-09-09 22:49 ` Andrii Nakryiko [this message]
2024-09-10 2:51 ` [PATCH 1/3] uprobes: allow put_uprobe() from non-sleepable softirq context Alexei Starovoitov
2024-09-10 5:13 ` Andrii Nakryiko
2024-09-10 15:56 ` Alexei Starovoitov
2024-09-10 17:46 ` Andrii Nakryiko
2024-09-15 14:49 ` Oleg Nesterov
2024-09-17 8:19 ` Andrii Nakryiko
2024-10-04 20:18 ` Andrii Nakryiko
2024-09-09 22:49 ` [PATCH 2/3] uprobes: SRCU-protect uretprobe lifetime (with timeout) Andrii Nakryiko
2024-09-09 22:49 ` [PATCH 3/3] uprobes: implement SRCU-protected lifetime for single-stepped uprobe Andrii Nakryiko
2024-09-15 14:51 ` Oleg Nesterov
2024-09-17 8:20 ` Andrii Nakryiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240909224903.3498207-2-andrii@kernel.org \
--to=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=oleg@redhat.com \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.