^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * trace_boot.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Tracing kernel boot-time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define pr_fmt(fmt) "trace_boot: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bootconfig.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/cpumask.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/ftrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/trace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/trace_events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define MAX_BUF_LEN 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) trace_boot_set_instance_options(struct trace_array *tr, struct xbc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct xbc_node *anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) char buf[MAX_BUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned long v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Common ftrace options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) xbc_node_for_each_array_value(node, "options", anode, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (strlcpy(buf, p, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) pr_err("String is too long: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (trace_set_options(tr, buf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) pr_err("Failed to set option: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) p = xbc_node_find_value(node, "tracing_on", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (p && *p != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (kstrtoul(p, 10, &v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) pr_err("Failed to set tracing on: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) tracer_tracing_on(tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) tracer_tracing_off(tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) p = xbc_node_find_value(node, "trace_clock", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (p && *p != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (tracing_set_clock(tr, p) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) pr_err("Failed to set trace clock: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) p = xbc_node_find_value(node, "buffer_size", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (p && *p != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) v = memparse(p, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (v < PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) pr_err("Buffer size is too small: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (tracing_resize_ring_buffer(tr, v, RING_BUFFER_ALL_CPUS) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) pr_err("Failed to resize trace buffer to %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) p = xbc_node_find_value(node, "cpumask", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (p && *p != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) cpumask_var_t new_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (alloc_cpumask_var(&new_mask, GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (cpumask_parse(p, new_mask) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) tracing_set_cpumask(tr, new_mask) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) pr_err("Failed to set new CPU mask %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) free_cpumask_var(new_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #ifdef CONFIG_EVENT_TRACING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) trace_boot_enable_events(struct trace_array *tr, struct xbc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct xbc_node *anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) char buf[MAX_BUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) xbc_node_for_each_array_value(node, "events", anode, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (strlcpy(buf, p, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) pr_err("String is too long: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (ftrace_set_clr_event(tr, buf, 1) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pr_err("Failed to enable event: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #ifdef CONFIG_KPROBE_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) trace_boot_add_kprobe_event(struct xbc_node *node, const char *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct dynevent_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct xbc_node *anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) char buf[MAX_BUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) const char *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) xbc_node_for_each_array_value(node, "probes", anode, val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) kprobe_event_cmd_init(&cmd, buf, MAX_BUF_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ret = kprobe_event_gen_cmd_start(&cmd, event, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) pr_err("Failed to generate probe: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ret = kprobe_event_gen_cmd_end(&cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pr_err("Failed to add probe: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) trace_boot_add_kprobe_event(struct xbc_node *node, const char *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pr_err("Kprobe event is not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #ifdef CONFIG_SYNTH_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) trace_boot_add_synth_event(struct xbc_node *node, const char *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct dynevent_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct xbc_node *anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) char buf[MAX_BUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) synth_event_cmd_init(&cmd, buf, MAX_BUF_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ret = synth_event_gen_cmd_start(&cmd, event, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) xbc_node_for_each_array_value(node, "fields", anode, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ret = synth_event_add_field_str(&cmd, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret = synth_event_gen_cmd_end(&cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) pr_err("Failed to add synthetic event: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) trace_boot_add_synth_event(struct xbc_node *node, const char *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) pr_err("Synthetic event is not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) trace_boot_init_one_event(struct trace_array *tr, struct xbc_node *gnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct xbc_node *enode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct trace_event_file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct xbc_node *anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) char buf[MAX_BUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) const char *p, *group, *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) group = xbc_node_get_data(gnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) event = xbc_node_get_data(enode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!strcmp(group, "kprobes"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (trace_boot_add_kprobe_event(enode, event) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (!strcmp(group, "synthetic"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (trace_boot_add_synth_event(enode, event) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mutex_lock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) file = find_event_file(tr, group, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pr_err("Failed to find event: %s:%s\n", group, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) p = xbc_node_find_value(enode, "filter", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (p && *p != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (strlcpy(buf, p, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) pr_err("filter string is too long: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) else if (apply_event_filter(file, buf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) pr_err("Failed to apply filter: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (IS_ENABLED(CONFIG_HIST_TRIGGERS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) xbc_node_for_each_array_value(enode, "actions", anode, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (strlcpy(buf, p, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) pr_err("action string is too long: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) else if (trigger_process_regex(file, buf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) pr_err("Failed to apply an action: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) } else if (xbc_node_find_value(enode, "actions", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) pr_err("Failed to apply event actions because CONFIG_HIST_TRIGGERS is not set.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (xbc_node_find_value(enode, "enable", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (trace_event_enable_disable(file, 1, 0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pr_err("Failed to enable event node: %s:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) group, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) mutex_unlock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) trace_boot_init_events(struct trace_array *tr, struct xbc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct xbc_node *gnode, *enode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) node = xbc_node_find_child(node, "event");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* per-event key starts with "event.GROUP.EVENT" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) xbc_node_for_each_subkey(node, gnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) xbc_node_for_each_subkey(gnode, enode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) trace_boot_init_one_event(tr, gnode, enode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define trace_boot_enable_events(tr, node) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define trace_boot_init_events(tr, node) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #ifdef CONFIG_DYNAMIC_FTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) trace_boot_set_ftrace_filter(struct trace_array *tr, struct xbc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct xbc_node *anode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) char *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) xbc_node_for_each_array_value(node, "ftrace.filters", anode, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) q = kstrdup(p, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ftrace_set_filter(tr->ops, q, strlen(q), 0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) pr_err("Failed to add %s to ftrace filter\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ftrace_filter_param = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) kfree(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) xbc_node_for_each_array_value(node, "ftrace.notraces", anode, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) q = kstrdup(p, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (ftrace_set_notrace(tr->ops, q, strlen(q), 0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pr_err("Failed to add %s to ftrace filter\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ftrace_filter_param = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) kfree(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #define trace_boot_set_ftrace_filter(tr, node) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) trace_boot_enable_tracer(struct trace_array *tr, struct xbc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) trace_boot_set_ftrace_filter(tr, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) p = xbc_node_find_value(node, "tracer", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (p && *p != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (tracing_set_tracer(tr, p) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) pr_err("Failed to set given tracer: %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Since tracer can free snapshot buffer, allocate snapshot here.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (xbc_node_find_value(node, "alloc_snapshot", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (tracing_alloc_snapshot_instance(tr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) pr_err("Failed to allocate snapshot buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) trace_boot_init_one_instance(struct trace_array *tr, struct xbc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) trace_boot_set_instance_options(tr, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) trace_boot_init_events(tr, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) trace_boot_enable_events(tr, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) trace_boot_enable_tracer(tr, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) trace_boot_init_instances(struct xbc_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct xbc_node *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct trace_array *tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) node = xbc_node_find_child(node, "instance");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) xbc_node_for_each_subkey(node, inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) p = xbc_node_get_data(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!p || *p == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) tr = trace_array_get_by_name(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (!tr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) pr_err("Failed to get trace instance %s\n", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) trace_boot_init_one_instance(tr, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) trace_array_put(tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int __init trace_boot_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct xbc_node *trace_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct trace_array *tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) trace_node = xbc_find_node("ftrace");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (!trace_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) tr = top_trace_array();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!tr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Global trace array is also one instance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) trace_boot_init_one_instance(tr, trace_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) trace_boot_init_instances(trace_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) disable_tracing_selftest("running boot-time tracing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * Start tracing at the end of core-initcall, so that it starts tracing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * from the beginning of postcore_initcall.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) core_initcall_sync(trace_boot_init);