[RFC PATCH v3 15/19] tracing/boot: Add instance node support

From: Masami Hiramatsu
Date: Sun Aug 25 2019 - 23:18:44 EST


Add instance node support to boottime tracing. User can set
some options and event nodes under instance node.

- ftrace.instance.INSTANCE[...];
Add new INSTANCE instance. Some options and event nodes
are acceptable for instance node.

Signed-off-by: Masami Hiramatsu <mhiramat@xxxxxxxxxx>
---
kernel/trace/trace_boot.c | 72 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 57 insertions(+), 15 deletions(-)

diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
index 2e9fddff660f..74cffecd12a4 100644
--- a/kernel/trace/trace_boot.c
+++ b/kernel/trace/trace_boot.c
@@ -21,15 +21,15 @@ extern int tracing_set_tracer(struct trace_array *tr, const char *buf);
extern void __init trace_init_tracepoint_printk(void);
extern ssize_t tracing_resize_ring_buffer(struct trace_array *tr,
unsigned long size, int cpu_id);
+extern struct trace_array *trace_array_create(const char *name);

static void __init
-trace_boot_set_ftrace_options(struct trace_array *tr, struct skc_node *node)
+trace_boot_set_instance_options(struct trace_array *tr, struct skc_node *node)
{
struct skc_node *anode;
const char *p;
char buf[MAX_BUF_LEN];
unsigned long v = 0;
- int err;

/* Common ftrace options */
skc_node_for_each_array_value(node, "options", anode, p) {
@@ -48,6 +48,23 @@ trace_boot_set_ftrace_options(struct trace_array *tr, struct skc_node *node)
pr_err("Failed to set trace clock: %s\n", p);
}

+ p = skc_node_find_value(node, "buffer_size", NULL);
+ if (p && *p != '\0') {
+ v = memparse(p, NULL);
+ if (v < PAGE_SIZE)
+ pr_err("Buffer size is too small: %s\n", p);
+ if (tracing_resize_ring_buffer(tr, v, RING_BUFFER_ALL_CPUS) < 0)
+ pr_err("Failed to resize trace buffer to %s\n", p);
+ }
+}
+
+static void __init
+trace_boot_set_global_options(struct trace_array *tr, struct skc_node *node)
+{
+ unsigned long v = 0;
+ const char *p;
+ int err;
+
/* Command line boot options */
p = skc_node_find_value(node, "dump_on_oops", NULL);
if (p) {
@@ -64,15 +81,6 @@ trace_boot_set_ftrace_options(struct trace_array *tr, struct skc_node *node)
if (skc_node_find_value(node, "tp_printk", NULL))
trace_init_tracepoint_printk();

- p = skc_node_find_value(node, "buffer_size", NULL);
- if (p && *p != '\0') {
- v = memparse(p, NULL);
- if (v < PAGE_SIZE)
- pr_err("Buffer size is too small: %s\n", p);
- if (tracing_resize_ring_buffer(tr, v, RING_BUFFER_ALL_CPUS) < 0)
- pr_err("Failed to resize trace buffer to %s\n", p);
- }
-
if (skc_node_find_value(node, "alloc_snapshot", NULL))
if (tracing_alloc_snapshot() < 0)
pr_err("Failed to allocate snapshot buffer\n");
@@ -266,6 +274,40 @@ trace_boot_enable_tracer(struct trace_array *tr, struct skc_node *node)
}
}

+static void __init
+trace_boot_init_one_instance(struct trace_array *tr, struct skc_node *node)
+{
+ trace_boot_set_instance_options(tr, node);
+ trace_boot_init_events(tr, node);
+ trace_boot_enable_events(tr, node);
+ trace_boot_enable_tracer(tr, node);
+}
+
+static void __init
+trace_boot_init_instances(struct skc_node *node)
+{
+ struct skc_node *inode;
+ struct trace_array *tr;
+ const char *p;
+
+ node = skc_node_find_child(node, "instance");
+ if (!node)
+ return;
+
+ skc_node_for_each_child(node, inode) {
+ p = skc_node_get_data(inode);
+ if (!p || *p == '\0')
+ continue;
+
+ tr = trace_array_create(p);
+ if (IS_ERR(tr)) {
+ pr_err("Failed to create instance %s\n", p);
+ continue;
+ }
+ trace_boot_init_one_instance(tr, inode);
+ }
+}
+
static int __init trace_boot_init(void)
{
struct skc_node *trace_node;
@@ -279,10 +321,10 @@ static int __init trace_boot_init(void)
if (!tr)
return 0;

- trace_boot_set_ftrace_options(tr, trace_node);
- trace_boot_init_events(tr, trace_node);
- trace_boot_enable_events(tr, trace_node);
- trace_boot_enable_tracer(tr, trace_node);
+ trace_boot_set_global_options(tr, trace_node);
+ /* Global trace array is also one instance */
+ trace_boot_init_one_instance(tr, trace_node);
+ trace_boot_init_instances(trace_node);

return 0;
}