lkml.org 
[lkml]   [2020]   [Jan]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[for-next][PATCH 21/26] tracing/boot: Add synthetic event support
    From: Masami Hiramatsu <mhiramat@kernel.org>

    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>
    ---
    kernel/trace/trace_boot.c | 47 ++++++++++++++++++++++++++++++++
    kernel/trace/trace_events_hist.c | 5 ++++
    2 files changed, 52 insertions(+)

    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);
    diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
    index 1cb4c4c8e5b7..8e90f1ada437 100644
    --- a/kernel/trace/trace_events_hist.c
    +++ b/kernel/trace/trace_events_hist.c
    @@ -1384,6 +1384,11 @@ static int create_or_delete_synth_event(int argc, char **argv)
    return ret == -ECANCELED ? -EINVAL : ret;
    }

    +int synth_event_run_command(const char *command)
    +{
    + return trace_run_command(command, create_or_delete_synth_event);
    +}
    +
    static int synth_event_create(int argc, const char **argv)
    {
    const char *name = argv[0];
    --
    2.24.1

    \
     
     \ /
      Last update: 2020-01-14 22:05    [W:4.190 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site