tracing/boot: Support multiple histograms for each event
authorMasami Hiramatsu <mhiramat@kernel.org>
Tue, 10 Aug 2021 02:07:36 +0000 (11:07 +0900)
committerSteven Rostedt (VMware) <rostedt@goodmis.org>
Mon, 16 Aug 2021 15:37:21 +0000 (11:37 -0400)
Add multiple histograms support for each event. This allows
user to set multiple histograms to an event.

ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist[.N] {
...
}

The 'N' is a digit started string and it can be omitted
for the default histogram.

For example, multiple hist triggers example in the
Documentation/trace/histogram.rst can be written as below;

ftrace.event.net.netif_receive_skb.hist {
1 {
keys = skbaddr.hex
values = len
filter = len < 0
}
2 {
keys = skbaddr.hex
values = len
filter = len > 4096
}
3 {
keys = skbaddr.hex
values = len
filter = len == 256
}
4 {
keys = skbaddr.hex
values = len
}
5 {
keys = len
values = common_preempt_count
}
}

Link: https://lkml.kernel.org/r/162856125628.203126.15846930277378572120.stgit@devnote2
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
kernel/trace/trace_boot.c

index f024f27..1a2b270 100644 (file)
@@ -324,7 +324,7 @@ trace_boot_hist_add_handlers(struct xbc_node *hnode, char **bufp,
 /*
  * Histogram boottime tracing syntax.
  *
- * ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist {
+ * ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist[.N] {
  *     keys = <KEY>[,...]
  *     values = <VAL>[,...]
  *     sort = <SORT-KEY>[,...]
@@ -415,11 +415,37 @@ trace_boot_compose_hist_cmd(struct xbc_node *hnode, char *buf, size_t size)
 
        return 0;
 }
+
+static void __init
+trace_boot_init_histograms(struct trace_event_file *file,
+                          struct xbc_node *hnode, char *buf, size_t size)
+{
+       struct xbc_node *node;
+       const char *p;
+
+       xbc_node_for_each_subkey(hnode, node) {
+               p = xbc_node_get_data(node);
+               if (!isdigit(p[0]))
+                       continue;
+               /* All digit started node should be instances. */
+               if (trace_boot_compose_hist_cmd(node, buf, size) == 0) {
+                       if (trigger_process_regex(file, buf) < 0)
+                               pr_err("Failed to apply hist trigger: %s\n", buf);
+               }
+       }
+
+       if (xbc_node_find_child(hnode, "keys")) {
+               if (trace_boot_compose_hist_cmd(hnode, buf, size) == 0)
+                       if (trigger_process_regex(file, buf) < 0)
+                               pr_err("Failed to apply hist trigger: %s\n", buf);
+       }
+}
 #else
-static int __init
-trace_boot_compose_hist_cmd(struct xbc_node *hnode, char *buf, size_t size)
+static void __init
+trace_boot_init_histograms(struct trace_event_file *file,
+                          struct xbc_node *hnode, char *buf, size_t size)
 {
-       return -EOPNOTSUPP;
+       /* do nothing */
 }
 #endif
 
@@ -465,11 +491,8 @@ trace_boot_init_one_event(struct trace_array *tr, struct xbc_node *gnode,
                                pr_err("Failed to apply an action: %s\n", buf);
                }
                anode = xbc_node_find_child(enode, "hist");
-               if (anode &&
-                   trace_boot_compose_hist_cmd(anode, buf, ARRAY_SIZE(buf)) == 0) {
-                       if (trigger_process_regex(file, buf) < 0)
-                               pr_err("Failed to apply hist trigger: %s\n", buf);
-               }
+               if (anode)
+                       trace_boot_init_histograms(file, anode, buf, ARRAY_SIZE(buf));
        } else if (xbc_node_find_value(enode, "actions", NULL))
                pr_err("Failed to apply event actions because CONFIG_HIST_TRIGGERS is not set.\n");