lkml.org 
[lkml]   [2019]   [Aug]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[RFC PATCH v3 13/19] tracing/boot Add kprobe event support
Date
Add kprobe event support on event node. If the group name of event
is "kprobes", boottime trace defines new probe event according
to "probes" values.

- ftrace.event.kprobes.EVENT.probes = PROBE[, PROBE2...];
Defines new kprobe event based on PROBEs. It is able to define
multiple probes on one event, but those must have same type of
arguments.

For example,

ftrace.events.kprobes.myevent {
probes = "vfs_read $arg1 $arg2";
enable;
}

This will add kprobes:myevent on vfs_read with the 1st and the 2nd
arguments.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
kernel/trace/trace_boot.c | 46 +++++++++++++++++++++++++++++++++++++++++++
kernel/trace/trace_kprobe.c | 5 +++++
2 files changed, 51 insertions(+)

diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
index cfd628c16761..40c89c7ceee0 100644
--- a/kernel/trace/trace_boot.c
+++ b/kernel/trace/trace_boot.c
@@ -100,6 +100,48 @@ trace_boot_enable_events(struct trace_array *tr, struct skc_node *node)
}
}

+#ifdef CONFIG_KPROBE_EVENTS
+extern int trace_kprobe_run_command(const char *command);
+
+static int __init
+trace_boot_add_kprobe_event(struct skc_node *node, const char *event)
+{
+ struct skc_node *anode;
+ char buf[MAX_BUF_LEN];
+ const char *val;
+ char *p;
+ int len;
+
+ len = snprintf(buf, ARRAY_SIZE(buf) - 1, "p:kprobes/%s ", event);
+ if (len >= ARRAY_SIZE(buf)) {
+ pr_err("Event name is too long: %s\n", event);
+ return -E2BIG;
+ }
+ p = buf + len;
+ len = ARRAY_SIZE(buf) - len;
+
+ skc_node_for_each_array_value(node, "probes", anode, val) {
+ if (strlcpy(p, val, len) >= len) {
+ pr_err("Probe definition is too long: %s\n", val);
+ return -E2BIG;
+ }
+ if (trace_kprobe_run_command(buf) < 0) {
+ pr_err("Failed to add probe: %s\n", buf);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+#else
+static inline int __init
+trace_boot_add_kprobe_event(struct skc_node *node, const char *event)
+{
+ pr_err("Kprobe event is not supported.\n");
+ return -ENOTSUPP;
+}
+#endif
+
static void __init
trace_boot_init_one_event(struct trace_array *tr, struct skc_node *gnode,
struct skc_node *enode)
@@ -112,6 +154,10 @@ trace_boot_init_one_event(struct trace_array *tr, struct skc_node *gnode,
group = skc_node_get_data(gnode);
event = skc_node_get_data(enode);

+ if (!strcmp(group, "kprobes"))
+ if (trace_boot_add_kprobe_event(enode, event) < 0)
+ return;
+
mutex_lock(&event_mutex);
file = find_event_file(tr, group, event);
if (!file) {
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 5135c07b6557..03ce60928c18 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -728,6 +728,11 @@ static int create_or_delete_trace_kprobe(int argc, char **argv)
return ret == -ECANCELED ? -EINVAL : ret;
}

+int trace_kprobe_run_command(const char *command)
+{
+ return trace_run_command(command, create_or_delete_trace_kprobe);
+}
+
static int trace_kprobe_release(struct dyn_event *ev)
{
struct trace_kprobe *tk = to_trace_kprobe(ev);
\
 
 \ /
  Last update: 2019-08-26 05:20    [W:0.585 / U:0.392 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site