diff options
author | Masami Hiramatsu <mhiramat@kernel.org> | 2020-01-11 01:06:52 +0900 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2020-01-13 13:19:42 -0500 |
commit | 3fbe2d6e1fce255d918b622fb2af22e98364a154 (patch) | |
tree | d09c96f98d9a1a70ec0fe68185a0889d1147ae40 /kernel/trace/trace_boot.c | |
parent | 4d655281eb1bb59fad021c0f68afd033f8d0320d (diff) |
tracing/boot: Add synthetic event support
Add synthetic event node support to boot time tracing.
The synthetic event is a kind of event node, but the group
name is "synthetic".
- ftrace.event.synthetic.EVENT.fields = FIELD[, FIELD2...]
Defines new synthetic event with FIELDs. Each field should be
"type varname".
The synthetic node requires "fields" string arraies, which defines
the fields as same as tracing/synth_events interface.
Link: http://lkml.kernel.org/r/157867241236.17873.12411615143321557709.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_boot.c')
-rw-r--r-- | kernel/trace/trace_boot.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c index a11dc60299fb..3054921b0877 100644 --- a/kernel/trace/trace_boot.c +++ b/kernel/trace/trace_boot.c @@ -118,6 +118,50 @@ trace_boot_add_kprobe_event(struct xbc_node *node, const char *event) } #endif +#ifdef CONFIG_HIST_TRIGGERS +extern int synth_event_run_command(const char *command); + +static int __init +trace_boot_add_synth_event(struct xbc_node *node, const char *event) +{ + struct xbc_node *anode; + char buf[MAX_BUF_LEN], *q; + const char *p; + int len, delta, ret; + + len = ARRAY_SIZE(buf); + delta = snprintf(buf, len, "%s", event); + if (delta >= len) { + pr_err("Event name is too long: %s\n", event); + return -E2BIG; + } + len -= delta; q = buf + delta; + + xbc_node_for_each_array_value(node, "fields", anode, p) { + delta = snprintf(q, len, " %s;", p); + if (delta >= len) { + pr_err("fields string is too long: %s\n", p); + return -E2BIG; + } + len -= delta; q += delta; + } + + ret = synth_event_run_command(buf); + if (ret < 0) + pr_err("Failed to add synthetic event: %s\n", buf); + + + return ret; +} +#else +static inline int __init +trace_boot_add_synth_event(struct xbc_node *node, const char *event) +{ + pr_err("Synthetic event is not supported.\n"); + return -ENOTSUPP; +} +#endif + static void __init trace_boot_init_one_event(struct trace_array *tr, struct xbc_node *gnode, struct xbc_node *enode) @@ -133,6 +177,9 @@ trace_boot_init_one_event(struct trace_array *tr, struct xbc_node *gnode, if (!strcmp(group, "kprobes")) if (trace_boot_add_kprobe_event(enode, event) < 0) return; + if (!strcmp(group, "synthetic")) + if (trace_boot_add_synth_event(enode, event) < 0) + return; mutex_lock(&event_mutex); file = find_event_file(tr, group, event); |