From: Masami Hiramatsu <mhiramat@kernel.org>
To: Brendan Gregg <brendan.d.gregg@gmail.com>,
Steven Rostedt <rostedt@goodmis.org>,
Alexei Starovoitov <ast@kernel.org>
Cc: mhiramat@kernel.org, Ingo Molnar <mingo@kernel.org>,
bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
Daniel Borkmann <daniel@iogearbox.net>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
"David S . Miller" <davem@davemloft.net>,
paulmck@kernel.org, joel@joelfernandes.org,
"Naveen N . Rao" <naveen.n.rao@linux.ibm.com>,
Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Subject: [RFT PATCH 05/13] tracing/kprobe: Use call_rcu to defer freeing event_file_link
Date: Thu, 16 Jan 2020 23:45:02 +0900 [thread overview]
Message-ID: <157918590192.29301.6909688694265698678.stgit@devnote2> (raw)
In-Reply-To: <157918584866.29301.6941815715391411338.stgit@devnote2>
Use call_rcu() to defer freeing event_file_link data
structure. This removes RCU synchronization from
per-probe event disabling operation.
Since unregistering kprobe event requires all handlers to
be disabled and have finished, this also introduces a
gatekeeper to ensure that. If there is any disabled event
which is not finished, the unregister process can synchronize
RCU once (IOW, may sleep a while.)
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
kernel/trace/trace_kprobe.c | 35 +++++++++++++++++++++++++++++------
kernel/trace/trace_probe.c | 10 ++++++++--
kernel/trace/trace_probe.h | 1 +
3 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index cbdc4f4e64c7..906af1ffe2b2 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -328,10 +328,25 @@ static inline int __enable_trace_kprobe(struct trace_kprobe *tk)
return ret;
}
+atomic_t trace_kprobe_disabled_finished;
+
+static void trace_kprobe_disabled_handlers_finish(void)
+{
+ if (atomic_read(&trace_kprobe_disabled_finished))
+ synchronize_rcu();
+}
+
+static void trace_kprobe_disabled_finish_cb(struct rcu_head *head)
+{
+ atomic_dec(&trace_kprobe_disabled_finished);
+ kfree(head);
+}
+
static void __disable_trace_kprobe(struct trace_probe *tp)
{
struct trace_probe *pos;
struct trace_kprobe *tk;
+ struct rcu_head *head;
list_for_each_entry(pos, trace_probe_probe_list(tp), list) {
tk = container_of(pos, struct trace_kprobe, tp);
@@ -342,6 +357,13 @@ static void __disable_trace_kprobe(struct trace_probe *tp)
else
disable_kprobe(&tk->rp.kp);
}
+
+ /* Handler exit gatekeeper */
+ head = kzalloc(sizeof(*head), GFP_KERNEL);
+ if (WARN_ON(!head))
+ return;
+ atomic_inc(&trace_kprobe_disabled_finished);
+ call_rcu(head, trace_kprobe_disabled_finish_cb);
}
/*
@@ -422,13 +444,11 @@ static int disable_trace_kprobe(struct trace_event_call *call,
out:
if (file)
- /*
- * Synchronization is done in below function. For perf event,
- * file == NULL and perf_trace_event_unreg() calls
- * tracepoint_synchronize_unregister() to ensure synchronize
- * event. We don't need to care about it.
- */
trace_probe_remove_file(tp, file);
+ /*
+ * We have no RCU synchronization here. Caller must wait for the
+ * completion of disabling.
+ */
return 0;
}
@@ -542,6 +562,9 @@ static int unregister_trace_kprobe(struct trace_kprobe *tk)
if (trace_probe_is_enabled(&tk->tp))
return -EBUSY;
+ /* Make sure all disabled trace_kprobe handlers finished */
+ trace_kprobe_disabled_handlers_finish();
+
/* Will fail if probe is being used by ftrace or perf */
if (unregister_kprobe_event(tk))
return -EBUSY;
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 905b10af5d5c..b18df8e1b2d6 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -1067,6 +1067,13 @@ struct event_file_link *trace_probe_get_file_link(struct trace_probe *tp,
return NULL;
}
+static void event_file_link_free_cb(struct rcu_head *head)
+{
+ struct event_file_link *link = container_of(head, typeof(*link), rcu);
+
+ kfree(link);
+}
+
int trace_probe_remove_file(struct trace_probe *tp,
struct trace_event_file *file)
{
@@ -1077,8 +1084,7 @@ int trace_probe_remove_file(struct trace_probe *tp,
return -ENOENT;
list_del_rcu(&link->list);
- synchronize_rcu();
- kfree(link);
+ call_rcu(&link->rcu, event_file_link_free_cb);
if (list_empty(&tp->event->files))
trace_probe_clear_flag(tp, TP_FLAG_TRACE);
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index 4ee703728aec..71ac01a50815 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -243,6 +243,7 @@ struct trace_probe {
struct event_file_link {
struct trace_event_file *file;
struct list_head list;
+ struct rcu_head rcu;
};
static inline bool trace_probe_test_flag(struct trace_probe *tp,
next prev parent reply other threads:[~2020-01-16 14:45 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-16 14:44 [RFT PATCH 00/13] tracing: kprobes: Introduce async unregistration Masami Hiramatsu
2020-01-16 14:44 ` [RFT PATCH 01/13] kprobes: Fix to protect kick_kprobe_optimizer() by kprobe_mutex Masami Hiramatsu
2020-01-16 14:44 ` [RFT PATCH 02/13] kprobes: Remove redundant arch_disarm_kprobe() call Masami Hiramatsu
2020-01-16 14:44 ` [RFT PATCH 03/13] kprobes: Postpone optimizer until a bunch of probes (un)registered Masami Hiramatsu
2020-01-16 14:44 ` [RFT PATCH 04/13] kprobes: Make optimizer delay to 1 second Masami Hiramatsu
2020-01-22 0:29 ` Steven Rostedt
2020-01-22 7:23 ` Masami Hiramatsu
2020-01-22 12:11 ` Steven Rostedt
2020-01-22 13:12 ` Masami Hiramatsu
2020-01-22 16:54 ` Paul E. McKenney
2020-01-23 1:33 ` Masami Hiramatsu
2020-01-23 2:26 ` Paul E. McKenney
2020-01-23 6:13 ` Masami Hiramatsu
2020-01-23 10:03 ` Paul E. McKenney
2020-01-16 14:45 ` Masami Hiramatsu [this message]
2020-01-27 15:02 ` [RFT PATCH 05/13] tracing/kprobe: Use call_rcu to defer freeing event_file_link kbuild test robot
2020-01-27 15:02 ` kbuild test robot
2020-01-27 15:02 ` [RFC PATCH] tracing/kprobe: trace_kprobe_disabled_finished can be static kbuild test robot
2020-01-27 15:02 ` kbuild test robot
2020-01-28 15:02 ` Masami Hiramatsu
2020-01-28 15:02 ` Masami Hiramatsu
2020-01-16 14:45 ` [RFT PATCH 06/13] kprobes: Enable kprobe-booster with CONFIG_PREEMPT=y Masami Hiramatsu
2020-01-16 14:45 ` [RFT PATCH 07/13] kprobes: Use normal list traversal API if a mutex is held Masami Hiramatsu
2020-01-16 14:45 ` [RFT PATCH 08/13] kprobes: Use workqueue for reclaiming kprobe insn cache pages Masami Hiramatsu
2020-01-16 14:45 ` [RFT PATCH 09/13] kprobes: Free kprobe_insn_page asynchronously Masami Hiramatsu
2020-01-16 14:45 ` [RFT PATCH 10/13] kprobes: Make free_*insn_slot() mutex-less Masami Hiramatsu
2020-01-16 14:46 ` [RFT PATCH 11/13] kprobes: Add asynchronous unregistration APIs Masami Hiramatsu
2020-01-16 14:46 ` [RFT PATCH 12/13] tracing/kprobe: Free probe event asynchronously Masami Hiramatsu
2020-01-16 14:46 ` [RFT PATCH 13/13] tracing/kprobe: perf_event: Remove local kprobe " Masami Hiramatsu
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=157918590192.29301.6909688694265698678.stgit@devnote2 \
--to=mhiramat@kernel.org \
--cc=acme@kernel.org \
--cc=anil.s.keshavamurthy@intel.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brendan.d.gregg@gmail.com \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=joel@joelfernandes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=naveen.n.rao@linux.ibm.com \
--cc=paulmck@kernel.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.