]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - kernel/trace/trace_events.c
tracing: keep the tracing buffer after self-test failure
[mirror_ubuntu-focal-kernel.git] / kernel / trace / trace_events.c
CommitLineData
b77e38aa
SR
1/*
2 * event tracer
3 *
4 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5 *
981d081e
SR
6 * - Added format output of fields of the trace point.
7 * This was based off of work by Tom Zanussi <tzanussi@gmail.com>.
8 *
b77e38aa
SR
9 */
10
11#include <linux/debugfs.h>
12#include <linux/uaccess.h>
13#include <linux/module.h>
14#include <linux/ctype.h>
15
91729ef9 16#include "trace_output.h"
b77e38aa 17
b628b3e6
SR
18#define TRACE_SYSTEM "TRACE_SYSTEM"
19
11a241a3
SR
20static DEFINE_MUTEX(event_mutex);
21
b77e38aa
SR
22static void ftrace_clear_events(void)
23{
24 struct ftrace_event_call *call = (void *)__start_ftrace_events;
25
26
27 while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
28
29 if (call->enabled) {
30 call->enabled = 0;
31 call->unregfunc();
32 }
33 call++;
34 }
35}
36
fd994989
SR
37static void ftrace_event_enable_disable(struct ftrace_event_call *call,
38 int enable)
39{
40
41 switch (enable) {
42 case 0:
43 if (call->enabled) {
44 call->enabled = 0;
45 call->unregfunc();
46 }
fd994989
SR
47 break;
48 case 1:
da4d0302 49 if (!call->enabled) {
fd994989
SR
50 call->enabled = 1;
51 call->regfunc();
52 }
fd994989
SR
53 break;
54 }
55}
56
b77e38aa
SR
57static int ftrace_set_clr_event(char *buf, int set)
58{
1473e441 59 struct ftrace_event_call *call = __start_ftrace_events;
b628b3e6
SR
60 char *event = NULL, *sub = NULL, *match;
61 int ret = -EINVAL;
62
63 /*
64 * The buf format can be <subsystem>:<event-name>
65 * *:<event-name> means any event by that name.
66 * :<event-name> is the same.
67 *
68 * <subsystem>:* means all events in that subsystem
69 * <subsystem>: means the same.
70 *
71 * <name> (no ':') means all events in a subsystem with
72 * the name <name> or any event that matches <name>
73 */
74
75 match = strsep(&buf, ":");
76 if (buf) {
77 sub = match;
78 event = buf;
79 match = NULL;
80
81 if (!strlen(sub) || strcmp(sub, "*") == 0)
82 sub = NULL;
83 if (!strlen(event) || strcmp(event, "*") == 0)
84 event = NULL;
85 }
b77e38aa 86
11a241a3 87 mutex_lock(&event_mutex);
ac199db0 88 for_each_event(call) {
b77e38aa 89
40e26815 90 if (!call->name || !call->regfunc)
1473e441
SR
91 continue;
92
b628b3e6
SR
93 if (match &&
94 strcmp(match, call->name) != 0 &&
95 strcmp(match, call->system) != 0)
96 continue;
97
98 if (sub && strcmp(sub, call->system) != 0)
99 continue;
100
101 if (event && strcmp(event, call->name) != 0)
b77e38aa 102 continue;
b77e38aa 103
fd994989
SR
104 ftrace_event_enable_disable(call, set);
105
b628b3e6 106 ret = 0;
b77e38aa 107 }
11a241a3
SR
108 mutex_unlock(&event_mutex);
109
b628b3e6 110 return ret;
b77e38aa
SR
111}
112
113/* 128 should be much more than enough */
114#define EVENT_BUF_SIZE 127
115
116static ssize_t
117ftrace_event_write(struct file *file, const char __user *ubuf,
118 size_t cnt, loff_t *ppos)
119{
120 size_t read = 0;
121 int i, set = 1;
122 ssize_t ret;
123 char *buf;
124 char ch;
125
126 if (!cnt || cnt < 0)
127 return 0;
128
1852fcce
SR
129 ret = tracing_update_buffers();
130 if (ret < 0)
131 return ret;
132
b77e38aa
SR
133 ret = get_user(ch, ubuf++);
134 if (ret)
135 return ret;
136 read++;
137 cnt--;
138
139 /* skip white space */
140 while (cnt && isspace(ch)) {
141 ret = get_user(ch, ubuf++);
142 if (ret)
143 return ret;
144 read++;
145 cnt--;
146 }
147
148 /* Only white space found? */
149 if (isspace(ch)) {
150 file->f_pos += read;
151 ret = read;
152 return ret;
153 }
154
155 buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
156 if (!buf)
157 return -ENOMEM;
158
159 if (cnt > EVENT_BUF_SIZE)
160 cnt = EVENT_BUF_SIZE;
161
162 i = 0;
163 while (cnt && !isspace(ch)) {
164 if (!i && ch == '!')
165 set = 0;
166 else
167 buf[i++] = ch;
168
169 ret = get_user(ch, ubuf++);
170 if (ret)
171 goto out_free;
172 read++;
173 cnt--;
174 }
175 buf[i] = 0;
176
177 file->f_pos += read;
178
179 ret = ftrace_set_clr_event(buf, set);
180 if (ret)
181 goto out_free;
182
183 ret = read;
184
185 out_free:
186 kfree(buf);
187
188 return ret;
189}
190
191static void *
192t_next(struct seq_file *m, void *v, loff_t *pos)
193{
194 struct ftrace_event_call *call = m->private;
195 struct ftrace_event_call *next = call;
196
197 (*pos)++;
198
40e26815
SR
199 for (;;) {
200 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
201 return NULL;
202
203 /*
204 * The ftrace subsystem is for showing formats only.
205 * They can not be enabled or disabled via the event files.
206 */
207 if (call->regfunc)
208 break;
209
210 call++;
211 next = call;
212 }
b77e38aa
SR
213
214 m->private = ++next;
215
216 return call;
217}
218
219static void *t_start(struct seq_file *m, loff_t *pos)
220{
221 return t_next(m, NULL, pos);
222}
223
224static void *
225s_next(struct seq_file *m, void *v, loff_t *pos)
226{
227 struct ftrace_event_call *call = m->private;
228 struct ftrace_event_call *next;
229
230 (*pos)++;
231
232 retry:
233 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
234 return NULL;
235
236 if (!call->enabled) {
237 call++;
238 goto retry;
239 }
240
241 next = call;
242 m->private = ++next;
243
244 return call;
245}
246
247static void *s_start(struct seq_file *m, loff_t *pos)
248{
249 return s_next(m, NULL, pos);
250}
251
252static int t_show(struct seq_file *m, void *v)
253{
254 struct ftrace_event_call *call = v;
255
b628b3e6
SR
256 if (strcmp(call->system, TRACE_SYSTEM) != 0)
257 seq_printf(m, "%s:", call->system);
b77e38aa
SR
258 seq_printf(m, "%s\n", call->name);
259
260 return 0;
261}
262
263static void t_stop(struct seq_file *m, void *p)
264{
265}
266
267static int
268ftrace_event_seq_open(struct inode *inode, struct file *file)
269{
270 int ret;
271 const struct seq_operations *seq_ops;
272
273 if ((file->f_mode & FMODE_WRITE) &&
274 !(file->f_flags & O_APPEND))
275 ftrace_clear_events();
276
277 seq_ops = inode->i_private;
278 ret = seq_open(file, seq_ops);
279 if (!ret) {
280 struct seq_file *m = file->private_data;
281
282 m->private = __start_ftrace_events;
283 }
284 return ret;
285}
286
1473e441
SR
287static ssize_t
288event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
289 loff_t *ppos)
290{
291 struct ftrace_event_call *call = filp->private_data;
292 char *buf;
293
da4d0302 294 if (call->enabled)
1473e441
SR
295 buf = "1\n";
296 else
297 buf = "0\n";
298
299 return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
300}
301
302static ssize_t
303event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
304 loff_t *ppos)
305{
306 struct ftrace_event_call *call = filp->private_data;
307 char buf[64];
308 unsigned long val;
309 int ret;
310
311 if (cnt >= sizeof(buf))
312 return -EINVAL;
313
314 if (copy_from_user(&buf, ubuf, cnt))
315 return -EFAULT;
316
317 buf[cnt] = 0;
318
319 ret = strict_strtoul(buf, 10, &val);
320 if (ret < 0)
321 return ret;
322
1852fcce
SR
323 ret = tracing_update_buffers();
324 if (ret < 0)
325 return ret;
326
1473e441
SR
327 switch (val) {
328 case 0:
1473e441 329 case 1:
11a241a3 330 mutex_lock(&event_mutex);
fd994989 331 ftrace_event_enable_disable(call, val);
11a241a3 332 mutex_unlock(&event_mutex);
1473e441
SR
333 break;
334
335 default:
336 return -EINVAL;
337 }
338
339 *ppos += cnt;
340
341 return cnt;
342}
343
91729ef9 344#undef FIELD
156b5f17 345#define FIELD(type, name) \
ce8eb2bf 346 #type, #name, offsetof(typeof(field), name), sizeof(field.name)
91729ef9
SR
347
348static int trace_write_header(struct trace_seq *s)
349{
350 struct trace_entry field;
351
352 /* struct trace_entry */
353 return trace_seq_printf(s,
ce8eb2bf
SR
354 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
355 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
356 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
357 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
358 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
91729ef9
SR
359 "\n",
360 FIELD(unsigned char, type),
361 FIELD(unsigned char, flags),
362 FIELD(unsigned char, preempt_count),
363 FIELD(int, pid),
364 FIELD(int, tgid));
365}
da4d0302 366
981d081e
SR
367static ssize_t
368event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
369 loff_t *ppos)
370{
371 struct ftrace_event_call *call = filp->private_data;
372 struct trace_seq *s;
373 char *buf;
374 int r;
375
c269fc8c
TZ
376 if (*ppos)
377 return 0;
378
981d081e
SR
379 s = kmalloc(sizeof(*s), GFP_KERNEL);
380 if (!s)
381 return -ENOMEM;
382
383 trace_seq_init(s);
384
c5e4e192
SR
385 /* If any of the first writes fail, so will the show_format. */
386
387 trace_seq_printf(s, "name: %s\n", call->name);
388 trace_seq_printf(s, "ID: %d\n", call->id);
389 trace_seq_printf(s, "format:\n");
91729ef9
SR
390 trace_write_header(s);
391
981d081e
SR
392 r = call->show_format(s);
393 if (!r) {
394 /*
395 * ug! The format output is bigger than a PAGE!!
396 */
397 buf = "FORMAT TOO BIG\n";
398 r = simple_read_from_buffer(ubuf, cnt, ppos,
399 buf, strlen(buf));
400 goto out;
401 }
402
403 r = simple_read_from_buffer(ubuf, cnt, ppos,
404 s->buffer, s->len);
405 out:
406 kfree(s);
407 return r;
408}
409
23725aee
PZ
410static ssize_t
411event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
412{
413 struct ftrace_event_call *call = filp->private_data;
414 struct trace_seq *s;
415 int r;
416
417 if (*ppos)
418 return 0;
419
420 s = kmalloc(sizeof(*s), GFP_KERNEL);
421 if (!s)
422 return -ENOMEM;
423
424 trace_seq_init(s);
425 trace_seq_printf(s, "%d\n", call->id);
426
427 r = simple_read_from_buffer(ubuf, cnt, ppos,
428 s->buffer, s->len);
429 kfree(s);
430 return r;
431}
432
b77e38aa
SR
433static const struct seq_operations show_event_seq_ops = {
434 .start = t_start,
435 .next = t_next,
436 .show = t_show,
437 .stop = t_stop,
438};
439
440static const struct seq_operations show_set_event_seq_ops = {
441 .start = s_start,
442 .next = s_next,
443 .show = t_show,
444 .stop = t_stop,
445};
446
2314c4ae
SR
447static const struct file_operations ftrace_avail_fops = {
448 .open = ftrace_event_seq_open,
449 .read = seq_read,
450 .llseek = seq_lseek,
451 .release = seq_release,
452};
453
b77e38aa
SR
454static const struct file_operations ftrace_set_event_fops = {
455 .open = ftrace_event_seq_open,
456 .read = seq_read,
457 .write = ftrace_event_write,
458 .llseek = seq_lseek,
459 .release = seq_release,
460};
461
1473e441
SR
462static const struct file_operations ftrace_enable_fops = {
463 .open = tracing_open_generic,
464 .read = event_enable_read,
465 .write = event_enable_write,
466};
467
981d081e
SR
468static const struct file_operations ftrace_event_format_fops = {
469 .open = tracing_open_generic,
470 .read = event_format_read,
471};
472
23725aee
PZ
473static const struct file_operations ftrace_event_id_fops = {
474 .open = tracing_open_generic,
475 .read = event_id_read,
476};
477
1473e441
SR
478static struct dentry *event_trace_events_dir(void)
479{
480 static struct dentry *d_tracer;
481 static struct dentry *d_events;
482
483 if (d_events)
484 return d_events;
485
486 d_tracer = tracing_init_dentry();
487 if (!d_tracer)
488 return NULL;
489
490 d_events = debugfs_create_dir("events", d_tracer);
491 if (!d_events)
492 pr_warning("Could not create debugfs "
493 "'events' directory\n");
494
495 return d_events;
496}
497
6ecc2d1c
SR
498struct event_subsystem {
499 struct list_head list;
500 const char *name;
501 struct dentry *entry;
502};
503
504static LIST_HEAD(event_subsystems);
505
506static struct dentry *
507event_subsystem_dir(const char *name, struct dentry *d_events)
508{
509 struct event_subsystem *system;
510
511 /* First see if we did not already create this dir */
512 list_for_each_entry(system, &event_subsystems, list) {
513 if (strcmp(system->name, name) == 0)
514 return system->entry;
515 }
516
517 /* need to create new entry */
518 system = kmalloc(sizeof(*system), GFP_KERNEL);
519 if (!system) {
520 pr_warning("No memory to create event subsystem %s\n",
521 name);
522 return d_events;
523 }
524
525 system->entry = debugfs_create_dir(name, d_events);
526 if (!system->entry) {
527 pr_warning("Could not create event subsystem %s\n",
528 name);
529 kfree(system);
530 return d_events;
531 }
532
533 system->name = name;
534 list_add(&system->list, &event_subsystems);
535
536 return system->entry;
537}
538
1473e441
SR
539static int
540event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
541{
542 struct dentry *entry;
fd994989 543 int ret;
1473e441 544
6ecc2d1c
SR
545 /*
546 * If the trace point header did not define TRACE_SYSTEM
547 * then the system would be called "TRACE_SYSTEM".
548 */
549 if (strcmp(call->system, "TRACE_SYSTEM") != 0)
550 d_events = event_subsystem_dir(call->system, d_events);
551
fd994989
SR
552 if (call->raw_init) {
553 ret = call->raw_init();
554 if (ret < 0) {
555 pr_warning("Could not initialize trace point"
556 " events/%s\n", call->name);
557 return ret;
558 }
559 }
560
1473e441
SR
561 call->dir = debugfs_create_dir(call->name, d_events);
562 if (!call->dir) {
563 pr_warning("Could not create debugfs "
564 "'%s' directory\n", call->name);
565 return -1;
566 }
567
770cb243
SR
568 if (call->regfunc) {
569 entry = debugfs_create_file("enable", 0644, call->dir, call,
570 &ftrace_enable_fops);
571 if (!entry)
572 pr_warning("Could not create debugfs "
573 "'%s/enable' entry\n", call->name);
574 }
1473e441 575
23725aee
PZ
576 if (call->id) {
577 entry = debugfs_create_file("id", 0444, call->dir, call,
578 &ftrace_event_id_fops);
579 if (!entry)
580 pr_warning("Could not create debugfs '%s/id' entry\n",
581 call->name);
582 }
583
981d081e
SR
584 /* A trace may not want to export its format */
585 if (!call->show_format)
586 return 0;
587
588 entry = debugfs_create_file("format", 0444, call->dir, call,
589 &ftrace_event_format_fops);
590 if (!entry)
591 pr_warning("Could not create debugfs "
592 "'%s/format' entry\n", call->name);
fd994989 593
1473e441
SR
594 return 0;
595}
596
b77e38aa
SR
597static __init int event_trace_init(void)
598{
1473e441 599 struct ftrace_event_call *call = __start_ftrace_events;
b77e38aa
SR
600 struct dentry *d_tracer;
601 struct dentry *entry;
1473e441 602 struct dentry *d_events;
b77e38aa
SR
603
604 d_tracer = tracing_init_dentry();
605 if (!d_tracer)
606 return 0;
607
2314c4ae
SR
608 entry = debugfs_create_file("available_events", 0444, d_tracer,
609 (void *)&show_event_seq_ops,
610 &ftrace_avail_fops);
611 if (!entry)
612 pr_warning("Could not create debugfs "
613 "'available_events' entry\n");
614
b77e38aa
SR
615 entry = debugfs_create_file("set_event", 0644, d_tracer,
616 (void *)&show_set_event_seq_ops,
617 &ftrace_set_event_fops);
618 if (!entry)
619 pr_warning("Could not create debugfs "
620 "'set_event' entry\n");
621
1473e441
SR
622 d_events = event_trace_events_dir();
623 if (!d_events)
624 return 0;
625
ac199db0 626 for_each_event(call) {
1473e441
SR
627 /* The linker may leave blanks */
628 if (!call->name)
629 continue;
630 event_create_dir(call, d_events);
631 }
632
b77e38aa
SR
633 return 0;
634}
635fs_initcall(event_trace_init);