1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * trace_boot.c
4 * Tracing kernel boot-time
5 */
6
7 #define pr_fmt(fmt) "trace_boot: " fmt
8
9 #include <linux/bootconfig.h>
10 #include <linux/cpumask.h>
11 #include <linux/ftrace.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/mutex.h>
15 #include <linux/string.h>
16 #include <linux/slab.h>
17 #include <linux/trace.h>
18 #include <linux/trace_events.h>
19
20 #include "trace.h"
21 #include "trace_dynevent.h"
22
23 #define MAX_BUF_LEN 256
24
25 static void __init
trace_boot_set_instance_options(struct trace_array * tr,struct xbc_node * node)26 trace_boot_set_instance_options(struct trace_array *tr, struct xbc_node *node)
27 {
28 struct xbc_node *anode;
29 const char *p;
30 char buf[MAX_BUF_LEN];
31 unsigned long v = 0;
32
33 /* Common ftrace options */
34 xbc_node_for_each_array_value(node, "options", anode, p) {
35 if (strscpy(buf, p, ARRAY_SIZE(buf)) < 0) {
36 pr_err("String is too long: %s\n", p);
37 continue;
38 }
39
40 if (trace_set_options(tr, buf) < 0)
41 pr_err("Failed to set option: %s\n", buf);
42 }
43
44 p = xbc_node_find_value(node, "tracing_on", NULL);
45 if (p && *p != '\0') {
46 if (kstrtoul(p, 10, &v))
47 pr_err("Failed to set tracing on: %s\n", p);
48 if (v)
49 tracer_tracing_on(tr);
50 else
51 tracer_tracing_off(tr);
52 }
53
54 p = xbc_node_find_value(node, "trace_clock", NULL);
55 if (p && *p != '\0') {
56 if (tracing_set_clock(tr, p) < 0)
57 pr_err("Failed to set trace clock: %s\n", p);
58 }
59
60 p = xbc_node_find_value(node, "buffer_size", NULL);
61 if (p && *p != '\0') {
62 v = memparse(p, NULL);
63 if (v < PAGE_SIZE)
64 pr_err("Buffer size is too small: %s\n", p);
65 if (trace_array_is_readonly(tr) ||
66 tracing_resize_ring_buffer(tr, v, RING_BUFFER_ALL_CPUS) < 0)
67 pr_err("Failed to resize trace buffer to %s\n", p);
68 }
69
70 p = xbc_node_find_value(node, "cpumask", NULL);
71 if (p && *p != '\0') {
72 cpumask_var_t new_mask;
73
74 if (alloc_cpumask_var(&new_mask, GFP_KERNEL)) {
75 if (cpumask_parse(p, new_mask) < 0 ||
76 tracing_set_cpumask(tr, new_mask) < 0)
77 pr_err("Failed to set new CPU mask %s\n", p);
78 free_cpumask_var(new_mask);
79 }
80 }
81 }
82
83 #ifdef CONFIG_EVENT_TRACING
84 static void __init
trace_boot_enable_events(struct trace_array * tr,struct xbc_node * node)85 trace_boot_enable_events(struct trace_array *tr, struct xbc_node *node)
86 {
87 struct xbc_node *anode;
88 char buf[MAX_BUF_LEN];
89 const char *p;
90
91 xbc_node_for_each_array_value(node, "events", anode, p) {
92 if (strscpy(buf, p, ARRAY_SIZE(buf)) < 0) {
93 pr_err("String is too long: %s\n", p);
94 continue;
95 }
96
97 if (ftrace_set_clr_event(tr, buf, 1) < 0)
98 pr_err("Failed to enable event: %s\n", p);
99 }
100 }
101
102 #ifdef CONFIG_KPROBE_EVENTS
103 static int __init
trace_boot_add_kprobe_event(struct xbc_node * node,const char * event)104 trace_boot_add_kprobe_event(struct xbc_node *node, const char *event)
105 {
106 struct dynevent_cmd cmd;
107 struct xbc_node *anode;
108 char buf[MAX_BUF_LEN];
109 const char *val;
110 int ret = 0;
111
112 xbc_node_for_each_array_value(node, "probes", anode, val) {
113 kprobe_event_cmd_init(&cmd, buf, MAX_BUF_LEN);
114
115 ret = kprobe_event_gen_cmd_start(&cmd, event, val);
116 if (ret) {
117 pr_err("Failed to generate probe: %s\n", buf);
118 break;
119 }
120
121 ret = kprobe_event_gen_cmd_end(&cmd);
122 if (ret) {
123 pr_err("Failed to add probe: %s\n", buf);
124 break;
125 }
126 }
127
128 return ret;
129 }
130 #else
131 static inline int __init
trace_boot_add_kprobe_event(struct xbc_node * node,const char * event)132 trace_boot_add_kprobe_event(struct xbc_node *node, const char *event)
133 {
134 pr_err("Kprobe event is not supported.\n");
135 return -ENOTSUPP;
136 }
137 #endif
138
139 #ifdef CONFIG_SYNTH_EVENTS
140 static int __init
trace_boot_add_synth_event(struct xbc_node * node,const char * event)141 trace_boot_add_synth_event(struct xbc_node *node, const char *event)
142 {
143 struct dynevent_cmd cmd;
144 struct xbc_node *anode;
145 char buf[MAX_BUF_LEN];
146 const char *p;
147 int ret;
148
149 synth_event_cmd_init(&cmd, buf, MAX_BUF_LEN);
150
151 ret = synth_event_gen_cmd_start(&cmd, event, NULL);
152 if (ret)
153 return ret;
154
155 xbc_node_for_each_array_value(node, "fields", anode, p) {
156 ret = synth_event_add_field_str(&cmd, p);
157 if (ret)
158 return ret;
159 }
160
161 ret = synth_event_gen_cmd_end(&cmd);
162 if (ret < 0)
163 pr_err("Failed to add synthetic event: %s\n", buf);
164
165 return ret;
166 }
167 #else
168 static inline int __init
trace_boot_add_synth_event(struct xbc_node * node,const char * event)169 trace_boot_add_synth_event(struct xbc_node *node, const char *event)
170 {
171 pr_err("Synthetic event is not supported.\n");
172 return -ENOTSUPP;
173 }
174 #endif
175
176 #if defined(CONFIG_EPROBE_EVENTS) || defined(CONFIG_FPROBE_EVENTS)
177 static int __init
trace_boot_add_probe_event(struct xbc_node * node,const char * group,const char * event,char type,const char * type_name)178 trace_boot_add_probe_event(struct xbc_node *node, const char *group,
179 const char *event, char type, const char *type_name)
180 {
181 struct xbc_node *anode;
182 char buf[MAX_BUF_LEN];
183 const char *val;
184 int ret = 0;
185
186 xbc_node_for_each_array_value(node, "probes", anode, val) {
187 if (val[0] == type && (val[1] == ':' || isspace(val[1]))) {
188 ret = strscpy(buf, val, MAX_BUF_LEN);
189 if (ret < 0) {
190 pr_err("%s command is too long: %s\n", type_name, val);
191 break;
192 }
193 } else {
194 ret = snprintf(buf, MAX_BUF_LEN, "%c:%s/%s %s", type, group, event, val);
195 if (ret >= MAX_BUF_LEN || ret < 0) {
196 pr_err("%s command is too long: %c:%s/%s %s\n",
197 type_name, type, group, event, val);
198 ret = -E2BIG;
199 break;
200 }
201 }
202
203 ret = dyn_event_create(buf, NULL);
204 if (ret) {
205 pr_err("Failed to add %s: %s\n", type_name, buf);
206 break;
207 }
208 }
209
210 return ret;
211 }
212 #endif
213
214 #ifdef CONFIG_EPROBE_EVENTS
215 static inline int __init
trace_boot_add_eprobe_event(struct xbc_node * node,const char * group,const char * event)216 trace_boot_add_eprobe_event(struct xbc_node *node, const char *group,
217 const char *event)
218 {
219 return trace_boot_add_probe_event(node, group, event, 'e', "eprobe");
220 }
221 #else
222 static inline int __init
trace_boot_add_eprobe_event(struct xbc_node * node,const char * group,const char * event)223 trace_boot_add_eprobe_event(struct xbc_node *node, const char *group,
224 const char *event)
225 {
226 pr_err("Event probe is not supported.\n");
227 return -EOPNOTSUPP;
228 }
229 #endif
230
231 #ifdef CONFIG_FPROBE_EVENTS
232 static inline int __init
trace_boot_add_fprobe_event(struct xbc_node * node,const char * group,const char * event)233 trace_boot_add_fprobe_event(struct xbc_node *node, const char *group,
234 const char *event)
235 {
236 return trace_boot_add_probe_event(node, group, event, 'f', "fprobe");
237 }
238
239 static inline int __init
trace_boot_add_tprobe_event(struct xbc_node * node,const char * group,const char * event)240 trace_boot_add_tprobe_event(struct xbc_node *node, const char *group,
241 const char *event)
242 {
243 return trace_boot_add_probe_event(node, group, event, 't', "tprobe");
244 }
245 #else
246 static inline int __init
trace_boot_add_fprobe_event(struct xbc_node * node,const char * group,const char * event)247 trace_boot_add_fprobe_event(struct xbc_node *node, const char *group,
248 const char *event)
249 {
250 pr_err("Fprobe event is not supported.\n");
251 return -EOPNOTSUPP;
252 }
253
254 static inline int __init
trace_boot_add_tprobe_event(struct xbc_node * node,const char * group,const char * event)255 trace_boot_add_tprobe_event(struct xbc_node *node, const char *group,
256 const char *event)
257 {
258 pr_err("Tracepoint probe is not supported.\n");
259 return -EOPNOTSUPP;
260 }
261 #endif
262
263 #ifdef CONFIG_HIST_TRIGGERS
264 static int __init __printf(3, 4)
append_printf(char ** bufp,char * end,const char * fmt,...)265 append_printf(char **bufp, char *end, const char *fmt, ...)
266 {
267 va_list args;
268 int ret;
269
270 if (*bufp == end)
271 return -ENOSPC;
272
273 va_start(args, fmt);
274 ret = vsnprintf(*bufp, end - *bufp, fmt, args);
275 if (ret < end - *bufp) {
276 *bufp += ret;
277 } else {
278 *bufp = end;
279 ret = -ERANGE;
280 }
281 va_end(args);
282
283 return ret;
284 }
285
286 static int __init
append_str_nospace(char ** bufp,char * end,const char * str)287 append_str_nospace(char **bufp, char *end, const char *str)
288 {
289 char *p = *bufp;
290 int len;
291
292 while (p < end - 1 && *str != '\0') {
293 if (!isspace(*str))
294 *(p++) = *str;
295 str++;
296 }
297 *p = '\0';
298 if (p == end - 1) {
299 *bufp = end;
300 return -ENOSPC;
301 }
302 len = p - *bufp;
303 *bufp = p;
304 return (int)len;
305 }
306
307 static int __init
trace_boot_hist_add_array(struct xbc_node * hnode,char ** bufp,char * end,const char * key)308 trace_boot_hist_add_array(struct xbc_node *hnode, char **bufp,
309 char *end, const char *key)
310 {
311 struct xbc_node *anode;
312 const char *p;
313 char sep;
314
315 p = xbc_node_find_value(hnode, key, &anode);
316 if (p) {
317 if (!anode) {
318 pr_err("hist.%s requires value(s).\n", key);
319 return -EINVAL;
320 }
321
322 append_printf(bufp, end, ":%s", key);
323 sep = '=';
324 xbc_array_for_each_value(anode, p) {
325 append_printf(bufp, end, "%c%s", sep, p);
326 if (sep == '=')
327 sep = ',';
328 }
329 } else
330 return -ENOENT;
331
332 return 0;
333 }
334
335 static int __init
trace_boot_hist_add_one_handler(struct xbc_node * hnode,char ** bufp,char * end,const char * handler,const char * param)336 trace_boot_hist_add_one_handler(struct xbc_node *hnode, char **bufp,
337 char *end, const char *handler,
338 const char *param)
339 {
340 struct xbc_node *knode, *anode;
341 const char *p;
342 char sep;
343
344 /* Compose 'handler' parameter */
345 p = xbc_node_find_value(hnode, param, NULL);
346 if (!p) {
347 pr_err("hist.%s requires '%s' option.\n",
348 xbc_node_get_data(hnode), param);
349 return -EINVAL;
350 }
351 append_printf(bufp, end, ":%s(%s)", handler, p);
352
353 /* Compose 'action' parameter */
354 knode = xbc_node_find_subkey(hnode, "trace");
355 if (!knode)
356 knode = xbc_node_find_subkey(hnode, "save");
357
358 if (knode) {
359 anode = xbc_node_get_child(knode);
360 if (!anode || !xbc_node_is_value(anode)) {
361 pr_err("hist.%s.%s requires value(s).\n",
362 xbc_node_get_data(hnode),
363 xbc_node_get_data(knode));
364 return -EINVAL;
365 }
366
367 append_printf(bufp, end, ".%s", xbc_node_get_data(knode));
368 sep = '(';
369 xbc_array_for_each_value(anode, p) {
370 append_printf(bufp, end, "%c%s", sep, p);
371 if (sep == '(')
372 sep = ',';
373 }
374 append_printf(bufp, end, ")");
375 } else if (xbc_node_find_subkey(hnode, "snapshot")) {
376 append_printf(bufp, end, ".snapshot()");
377 } else {
378 pr_err("hist.%s requires an action.\n",
379 xbc_node_get_data(hnode));
380 return -EINVAL;
381 }
382
383 return 0;
384 }
385
386 static int __init
trace_boot_hist_add_handlers(struct xbc_node * hnode,char ** bufp,char * end,const char * param)387 trace_boot_hist_add_handlers(struct xbc_node *hnode, char **bufp,
388 char *end, const char *param)
389 {
390 struct xbc_node *node;
391 const char *p, *handler;
392 int ret = 0;
393
394 handler = xbc_node_get_data(hnode);
395
396 xbc_node_for_each_subkey(hnode, node) {
397 p = xbc_node_get_data(node);
398 if (!isdigit(p[0]))
399 continue;
400 /* All digit started node should be instances. */
401 ret = trace_boot_hist_add_one_handler(node, bufp, end, handler, param);
402 if (ret < 0)
403 break;
404 }
405
406 if (xbc_node_find_subkey(hnode, param))
407 ret = trace_boot_hist_add_one_handler(hnode, bufp, end, handler, param);
408
409 return ret;
410 }
411
412 /*
413 * Histogram boottime tracing syntax.
414 *
415 * ftrace.[instance.INSTANCE.]event.GROUP.EVENT.hist[.N] {
416 * keys = <KEY>[,...]
417 * values = <VAL>[,...]
418 * sort = <SORT-KEY>[,...]
419 * size = <ENTRIES>
420 * name = <HISTNAME>
421 * var { <VAR> = <EXPR> ... }
422 * pause|continue|clear
423 * onmax|onchange[.N] { var = <VAR>; <ACTION> [= <PARAM>] }
424 * onmatch[.N] { event = <EVENT>; <ACTION> [= <PARAM>] }
425 * filter = <FILTER>
426 * }
427 *
428 * Where <ACTION> are;
429 *
430 * trace = <EVENT>, <ARG1>[, ...]
431 * save = <ARG1>[, ...]
432 * snapshot
433 */
434 static int __init
trace_boot_compose_hist_cmd(struct xbc_node * hnode,char * buf,size_t size)435 trace_boot_compose_hist_cmd(struct xbc_node *hnode, char *buf, size_t size)
436 {
437 struct xbc_node *node, *knode;
438 char *end = buf + size;
439 const char *p;
440 int ret = 0;
441
442 append_printf(&buf, end, "hist");
443
444 ret = trace_boot_hist_add_array(hnode, &buf, end, "keys");
445 if (ret < 0) {
446 if (ret == -ENOENT)
447 pr_err("hist requires keys.\n");
448 return -EINVAL;
449 }
450
451 ret = trace_boot_hist_add_array(hnode, &buf, end, "values");
452 if (ret == -EINVAL)
453 return ret;
454 ret = trace_boot_hist_add_array(hnode, &buf, end, "sort");
455 if (ret == -EINVAL)
456 return ret;
457
458 p = xbc_node_find_value(hnode, "size", NULL);
459 if (p)
460 append_printf(&buf, end, ":size=%s", p);
461
462 p = xbc_node_find_value(hnode, "name", NULL);
463 if (p)
464 append_printf(&buf, end, ":name=%s", p);
465
466 node = xbc_node_find_subkey(hnode, "var");
467 if (node) {
468 xbc_node_for_each_key_value(node, knode, p) {
469 /* Expression must not include spaces. */
470 append_printf(&buf, end, ":%s=",
471 xbc_node_get_data(knode));
472 append_str_nospace(&buf, end, p);
473 }
474 }
475
476 /* Histogram control attributes (mutual exclusive) */
477 if (xbc_node_find_value(hnode, "pause", NULL))
478 append_printf(&buf, end, ":pause");
479 else if (xbc_node_find_value(hnode, "continue", NULL))
480 append_printf(&buf, end, ":continue");
481 else if (xbc_node_find_value(hnode, "clear", NULL))
482 append_printf(&buf, end, ":clear");
483
484 /* Histogram handler and actions */
485 node = xbc_node_find_subkey(hnode, "onmax");
486 if (node && trace_boot_hist_add_handlers(node, &buf, end, "var") < 0)
487 return -EINVAL;
488 node = xbc_node_find_subkey(hnode, "onchange");
489 if (node && trace_boot_hist_add_handlers(node, &buf, end, "var") < 0)
490 return -EINVAL;
491 node = xbc_node_find_subkey(hnode, "onmatch");
492 if (node && trace_boot_hist_add_handlers(node, &buf, end, "event") < 0)
493 return -EINVAL;
494
495 p = xbc_node_find_value(hnode, "filter", NULL);
496 if (p)
497 append_printf(&buf, end, " if %s", p);
498
499 if (buf == end) {
500 pr_err("hist exceeds the max command length.\n");
501 return -E2BIG;
502 }
503
504 return 0;
505 }
506
507 static void __init
trace_boot_init_histograms(struct trace_event_file * file,struct xbc_node * hnode,char * buf,size_t size)508 trace_boot_init_histograms(struct trace_event_file *file,
509 struct xbc_node *hnode, char *buf, size_t size)
510 {
511 struct xbc_node *node;
512 const char *p;
513 char *tmp;
514
515 xbc_node_for_each_subkey(hnode, node) {
516 p = xbc_node_get_data(node);
517 if (!isdigit(p[0]))
518 continue;
519 /* All digit started node should be instances. */
520 if (trace_boot_compose_hist_cmd(node, buf, size) == 0) {
521 tmp = kstrdup(buf, GFP_KERNEL);
522 if (!tmp)
523 return;
524 if (trigger_process_regex(file, buf) < 0)
525 pr_err("Failed to apply hist trigger: %s\n", tmp);
526 kfree(tmp);
527 }
528 }
529
530 if (xbc_node_find_subkey(hnode, "keys")) {
531 if (trace_boot_compose_hist_cmd(hnode, buf, size) == 0) {
532 tmp = kstrdup(buf, GFP_KERNEL);
533 if (!tmp)
534 return;
535 if (trigger_process_regex(file, buf) < 0)
536 pr_err("Failed to apply hist trigger: %s\n", tmp);
537 kfree(tmp);
538 }
539 }
540 }
541 #else
542 static void __init
trace_boot_init_histograms(struct trace_event_file * file,struct xbc_node * hnode,char * buf,size_t size)543 trace_boot_init_histograms(struct trace_event_file *file,
544 struct xbc_node *hnode, char *buf, size_t size)
545 {
546 /* do nothing */
547 }
548 #endif
549
550 static void __init
trace_boot_init_one_event(struct trace_array * tr,struct xbc_node * gnode,struct xbc_node * enode)551 trace_boot_init_one_event(struct trace_array *tr, struct xbc_node *gnode,
552 struct xbc_node *enode)
553 {
554 struct trace_event_file *file;
555 struct xbc_node *anode;
556 char buf[MAX_BUF_LEN];
557 const char *p, *group, *event;
558
559 group = xbc_node_get_data(gnode);
560 event = xbc_node_get_data(enode);
561
562 if (!strcmp(group, "kprobes"))
563 if (trace_boot_add_kprobe_event(enode, event) < 0)
564 return;
565 if (!strcmp(group, "synthetic"))
566 if (trace_boot_add_synth_event(enode, event) < 0)
567 return;
568 if (!strcmp(group, "eprobes"))
569 if (trace_boot_add_eprobe_event(enode, group, event) < 0)
570 return;
571 if (!strcmp(group, "fprobes"))
572 if (trace_boot_add_fprobe_event(enode, group, event) < 0)
573 return;
574 if (!strcmp(group, "tracepoints") || !strcmp(group, "tprobes"))
575 if (trace_boot_add_tprobe_event(enode, group, event) < 0)
576 return;
577
578 mutex_lock(&event_mutex);
579 file = find_event_file(tr, group, event);
580 if (!file) {
581 pr_err("Failed to find event: %s:%s\n", group, event);
582 goto out;
583 }
584
585 p = xbc_node_find_value(enode, "filter", NULL);
586 if (p && *p != '\0') {
587 if (strscpy(buf, p, ARRAY_SIZE(buf)) < 0)
588 pr_err("filter string is too long: %s\n", p);
589 else if (apply_event_filter(file, buf) < 0)
590 pr_err("Failed to apply filter: %s\n", buf);
591 }
592
593 if (IS_ENABLED(CONFIG_HIST_TRIGGERS)) {
594 xbc_node_for_each_array_value(enode, "actions", anode, p) {
595 if (strscpy(buf, p, ARRAY_SIZE(buf)) < 0)
596 pr_err("action string is too long: %s\n", p);
597 else if (trigger_process_regex(file, buf) < 0)
598 pr_err("Failed to apply an action: %s\n", p);
599 }
600 anode = xbc_node_find_subkey(enode, "hist");
601 if (anode)
602 trace_boot_init_histograms(file, anode, buf, ARRAY_SIZE(buf));
603 } else if (xbc_node_find_value(enode, "actions", NULL))
604 pr_err("Failed to apply event actions because CONFIG_HIST_TRIGGERS is not set.\n");
605
606 if (xbc_node_find_value(enode, "enable", NULL)) {
607 if (trace_event_enable_disable(file, 1, 0) < 0)
608 pr_err("Failed to enable event node: %s:%s\n",
609 group, event);
610 }
611 out:
612 mutex_unlock(&event_mutex);
613 }
614
615 static void __init
trace_boot_init_events(struct trace_array * tr,struct xbc_node * node)616 trace_boot_init_events(struct trace_array *tr, struct xbc_node *node)
617 {
618 struct xbc_node *gnode, *enode;
619 bool enable, enable_all = false;
620 const char *data;
621
622 node = xbc_node_find_subkey(node, "event");
623 if (!node)
624 return;
625 /* per-event key starts with "event.GROUP.EVENT" */
626 xbc_node_for_each_subkey(node, gnode) {
627 data = xbc_node_get_data(gnode);
628 if (!strcmp(data, "enable")) {
629 enable_all = true;
630 continue;
631 }
632 enable = false;
633 xbc_node_for_each_subkey(gnode, enode) {
634 data = xbc_node_get_data(enode);
635 if (!strcmp(data, "enable")) {
636 enable = true;
637 continue;
638 }
639 trace_boot_init_one_event(tr, gnode, enode);
640 }
641 /* Event enablement must be done after event settings */
642 if (enable) {
643 data = xbc_node_get_data(gnode);
644 trace_array_set_clr_event(tr, data, NULL, true);
645 }
646 }
647 /* Ditto */
648 if (enable_all)
649 trace_array_set_clr_event(tr, NULL, NULL, true);
650 }
651 #else
652 #define trace_boot_enable_events(tr, node) do {} while (0)
653 #define trace_boot_init_events(tr, node) do {} while (0)
654 #endif
655
656 #ifdef CONFIG_DYNAMIC_FTRACE
657 static void __init
trace_boot_set_ftrace_filter(struct trace_array * tr,struct xbc_node * node)658 trace_boot_set_ftrace_filter(struct trace_array *tr, struct xbc_node *node)
659 {
660 struct xbc_node *anode;
661 const char *p;
662 char *q;
663
664 xbc_node_for_each_array_value(node, "ftrace.filters", anode, p) {
665 q = kstrdup(p, GFP_KERNEL);
666 if (!q)
667 return;
668 if (ftrace_set_filter(tr->ops, q, strlen(q), 0) < 0)
669 pr_err("Failed to add %s to ftrace filter\n", p);
670 else
671 ftrace_filter_param = true;
672 kfree(q);
673 }
674 xbc_node_for_each_array_value(node, "ftrace.notraces", anode, p) {
675 q = kstrdup(p, GFP_KERNEL);
676 if (!q)
677 return;
678 if (ftrace_set_notrace(tr->ops, q, strlen(q), 0) < 0)
679 pr_err("Failed to add %s to ftrace filter\n", p);
680 else
681 ftrace_filter_param = true;
682 kfree(q);
683 }
684 }
685 #else
686 #define trace_boot_set_ftrace_filter(tr, node) do {} while (0)
687 #endif
688
689 static void __init
trace_boot_enable_tracer(struct trace_array * tr,struct xbc_node * node)690 trace_boot_enable_tracer(struct trace_array *tr, struct xbc_node *node)
691 {
692 const char *p;
693
694 trace_boot_set_ftrace_filter(tr, node);
695
696 p = xbc_node_find_value(node, "tracer", NULL);
697 if (p && *p != '\0') {
698 if (trace_array_is_readonly(tr) || tracing_set_tracer(tr, p) < 0)
699 pr_err("Failed to set given tracer: %s\n", p);
700 }
701
702 /* Since tracer can free snapshot buffer, allocate snapshot here.*/
703 if (xbc_node_find_value(node, "alloc_snapshot", NULL)) {
704 if (tracing_alloc_snapshot_instance(tr) < 0)
705 pr_err("Failed to allocate snapshot buffer\n");
706 }
707 }
708
709 static void __init
trace_boot_init_one_instance(struct trace_array * tr,struct xbc_node * node)710 trace_boot_init_one_instance(struct trace_array *tr, struct xbc_node *node)
711 {
712 trace_boot_set_instance_options(tr, node);
713 trace_boot_init_events(tr, node);
714 trace_boot_enable_events(tr, node);
715 trace_boot_enable_tracer(tr, node);
716 }
717
718 static void __init
trace_boot_init_instances(struct xbc_node * node)719 trace_boot_init_instances(struct xbc_node *node)
720 {
721 struct xbc_node *inode;
722 struct trace_array *tr;
723 const char *p;
724
725 node = xbc_node_find_subkey(node, "instance");
726 if (!node)
727 return;
728
729 xbc_node_for_each_subkey(node, inode) {
730 p = xbc_node_get_data(inode);
731 if (!p || *p == '\0')
732 continue;
733
734 tr = trace_array_get_by_name(p, NULL);
735 if (!tr) {
736 pr_err("Failed to get trace instance %s\n", p);
737 continue;
738 }
739 trace_boot_init_one_instance(tr, inode);
740 trace_array_put(tr);
741 }
742 }
743
trace_boot_init(void)744 static int __init trace_boot_init(void)
745 {
746 struct xbc_node *trace_node;
747 struct trace_array *tr;
748
749 trace_node = xbc_find_node("ftrace");
750 if (!trace_node)
751 return 0;
752
753 tr = top_trace_array();
754 if (!tr)
755 return 0;
756
757 /* Global trace array is also one instance */
758 trace_boot_init_one_instance(tr, trace_node);
759 trace_boot_init_instances(trace_node);
760
761 disable_tracing_selftest("running boot-time tracing");
762
763 return 0;
764 }
765 /*
766 * Start tracing at the end of core-initcall, so that it starts tracing
767 * from the beginning of postcore_initcall.
768 */
769 core_initcall_sync(trace_boot_init);
770