tracing: add ftrace headers to event format files
[deliverable/linux.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
1473e441
SR
22#define events_for_each(event) \
23 for (event = __start_ftrace_events; \
24 (unsigned long)event < (unsigned long)__stop_ftrace_events; \
25 event++)
26
b77e38aa
SR
27void event_trace_printk(unsigned long ip, const char *fmt, ...)
28{
29 va_list ap;
30
31 va_start(ap, fmt);
32 tracing_record_cmdline(current);
33 trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap);
34 va_end(ap);
35}
36
37static void ftrace_clear_events(void)
38{
39 struct ftrace_event_call *call = (void *)__start_ftrace_events;
40
41
42 while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
43
44 if (call->enabled) {
45 call->enabled = 0;
46 call->unregfunc();
47 }
48 call++;
49 }
50}
51
fd994989
SR
52static void ftrace_event_enable_disable(struct ftrace_event_call *call,
53 int enable)
54{
55
56 switch (enable) {
57 case 0:
58 if (call->enabled) {
59 call->enabled = 0;
60 call->unregfunc();
61 }
62 if (call->raw_enabled) {
63 call->raw_enabled = 0;
64 call->raw_unreg();
65 }
66 break;
67 case 1:
68 if (!call->enabled &&
69 (call->type & TRACE_EVENT_TYPE_PRINTF)) {
70 call->enabled = 1;
71 call->regfunc();
72 }
73 if (!call->raw_enabled &&
74 (call->type & TRACE_EVENT_TYPE_RAW)) {
75 call->raw_enabled = 1;
76 call->raw_reg();
77 }
78 break;
79 }
80}
81
b77e38aa
SR
82static int ftrace_set_clr_event(char *buf, int set)
83{
1473e441 84 struct ftrace_event_call *call = __start_ftrace_events;
b628b3e6
SR
85 char *event = NULL, *sub = NULL, *match;
86 int ret = -EINVAL;
87
88 /*
89 * The buf format can be <subsystem>:<event-name>
90 * *:<event-name> means any event by that name.
91 * :<event-name> is the same.
92 *
93 * <subsystem>:* means all events in that subsystem
94 * <subsystem>: means the same.
95 *
96 * <name> (no ':') means all events in a subsystem with
97 * the name <name> or any event that matches <name>
98 */
99
100 match = strsep(&buf, ":");
101 if (buf) {
102 sub = match;
103 event = buf;
104 match = NULL;
105
106 if (!strlen(sub) || strcmp(sub, "*") == 0)
107 sub = NULL;
108 if (!strlen(event) || strcmp(event, "*") == 0)
109 event = NULL;
110 }
b77e38aa 111
11a241a3 112 mutex_lock(&event_mutex);
1473e441 113 events_for_each(call) {
b77e38aa 114
1473e441
SR
115 if (!call->name)
116 continue;
117
b628b3e6
SR
118 if (match &&
119 strcmp(match, call->name) != 0 &&
120 strcmp(match, call->system) != 0)
121 continue;
122
123 if (sub && strcmp(sub, call->system) != 0)
124 continue;
125
126 if (event && strcmp(event, call->name) != 0)
b77e38aa 127 continue;
b77e38aa 128
fd994989
SR
129 ftrace_event_enable_disable(call, set);
130
b628b3e6 131 ret = 0;
b77e38aa 132 }
11a241a3
SR
133 mutex_unlock(&event_mutex);
134
b628b3e6 135 return ret;
b77e38aa
SR
136}
137
138/* 128 should be much more than enough */
139#define EVENT_BUF_SIZE 127
140
141static ssize_t
142ftrace_event_write(struct file *file, const char __user *ubuf,
143 size_t cnt, loff_t *ppos)
144{
145 size_t read = 0;
146 int i, set = 1;
147 ssize_t ret;
148 char *buf;
149 char ch;
150
151 if (!cnt || cnt < 0)
152 return 0;
153
154 ret = get_user(ch, ubuf++);
155 if (ret)
156 return ret;
157 read++;
158 cnt--;
159
160 /* skip white space */
161 while (cnt && isspace(ch)) {
162 ret = get_user(ch, ubuf++);
163 if (ret)
164 return ret;
165 read++;
166 cnt--;
167 }
168
169 /* Only white space found? */
170 if (isspace(ch)) {
171 file->f_pos += read;
172 ret = read;
173 return ret;
174 }
175
176 buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
177 if (!buf)
178 return -ENOMEM;
179
180 if (cnt > EVENT_BUF_SIZE)
181 cnt = EVENT_BUF_SIZE;
182
183 i = 0;
184 while (cnt && !isspace(ch)) {
185 if (!i && ch == '!')
186 set = 0;
187 else
188 buf[i++] = ch;
189
190 ret = get_user(ch, ubuf++);
191 if (ret)
192 goto out_free;
193 read++;
194 cnt--;
195 }
196 buf[i] = 0;
197
198 file->f_pos += read;
199
200 ret = ftrace_set_clr_event(buf, set);
201 if (ret)
202 goto out_free;
203
204 ret = read;
205
206 out_free:
207 kfree(buf);
208
209 return ret;
210}
211
212static void *
213t_next(struct seq_file *m, void *v, loff_t *pos)
214{
215 struct ftrace_event_call *call = m->private;
216 struct ftrace_event_call *next = call;
217
218 (*pos)++;
219
220 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
221 return NULL;
222
223 m->private = ++next;
224
225 return call;
226}
227
228static void *t_start(struct seq_file *m, loff_t *pos)
229{
230 return t_next(m, NULL, pos);
231}
232
233static void *
234s_next(struct seq_file *m, void *v, loff_t *pos)
235{
236 struct ftrace_event_call *call = m->private;
237 struct ftrace_event_call *next;
238
239 (*pos)++;
240
241 retry:
242 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
243 return NULL;
244
245 if (!call->enabled) {
246 call++;
247 goto retry;
248 }
249
250 next = call;
251 m->private = ++next;
252
253 return call;
254}
255
256static void *s_start(struct seq_file *m, loff_t *pos)
257{
258 return s_next(m, NULL, pos);
259}
260
261static int t_show(struct seq_file *m, void *v)
262{
263 struct ftrace_event_call *call = v;
264
b628b3e6
SR
265 if (strcmp(call->system, TRACE_SYSTEM) != 0)
266 seq_printf(m, "%s:", call->system);
b77e38aa
SR
267 seq_printf(m, "%s\n", call->name);
268
269 return 0;
270}
271
272static void t_stop(struct seq_file *m, void *p)
273{
274}
275
276static int
277ftrace_event_seq_open(struct inode *inode, struct file *file)
278{
279 int ret;
280 const struct seq_operations *seq_ops;
281
282 if ((file->f_mode & FMODE_WRITE) &&
283 !(file->f_flags & O_APPEND))
284 ftrace_clear_events();
285
286 seq_ops = inode->i_private;
287 ret = seq_open(file, seq_ops);
288 if (!ret) {
289 struct seq_file *m = file->private_data;
290
291 m->private = __start_ftrace_events;
292 }
293 return ret;
294}
295
1473e441
SR
296static ssize_t
297event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
298 loff_t *ppos)
299{
300 struct ftrace_event_call *call = filp->private_data;
301 char *buf;
302
fd994989 303 if (call->enabled || call->raw_enabled)
1473e441
SR
304 buf = "1\n";
305 else
306 buf = "0\n";
307
308 return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
309}
310
311static ssize_t
312event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
313 loff_t *ppos)
314{
315 struct ftrace_event_call *call = filp->private_data;
316 char buf[64];
317 unsigned long val;
318 int ret;
319
320 if (cnt >= sizeof(buf))
321 return -EINVAL;
322
323 if (copy_from_user(&buf, ubuf, cnt))
324 return -EFAULT;
325
326 buf[cnt] = 0;
327
328 ret = strict_strtoul(buf, 10, &val);
329 if (ret < 0)
330 return ret;
331
332 switch (val) {
333 case 0:
1473e441 334 case 1:
11a241a3 335 mutex_lock(&event_mutex);
fd994989 336 ftrace_event_enable_disable(call, val);
11a241a3 337 mutex_unlock(&event_mutex);
1473e441
SR
338 break;
339
340 default:
341 return -EINVAL;
342 }
343
344 *ppos += cnt;
345
346 return cnt;
347}
348
fd994989
SR
349static ssize_t
350event_type_read(struct file *filp, char __user *ubuf, size_t cnt,
351 loff_t *ppos)
352{
353 struct ftrace_event_call *call = filp->private_data;
354 char buf[16];
355 int r = 0;
356
357 if (call->type & TRACE_EVENT_TYPE_PRINTF)
358 r += sprintf(buf, "printf\n");
359
360 if (call->type & TRACE_EVENT_TYPE_RAW)
361 r += sprintf(buf+r, "raw\n");
362
363 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
364}
365
366static ssize_t
367event_type_write(struct file *filp, const char __user *ubuf, size_t cnt,
368 loff_t *ppos)
369{
370 struct ftrace_event_call *call = filp->private_data;
371 char buf[64];
372
373 /*
374 * If there's only one type, we can't change it.
375 * And currently we always have printf type, and we
376 * may or may not have raw type.
377 *
378 * This is a redundant check, the file should be read
379 * only if this is the case anyway.
380 */
381
382 if (!call->raw_init)
383 return -EPERM;
384
385 if (cnt >= sizeof(buf))
386 return -EINVAL;
387
388 if (copy_from_user(&buf, ubuf, cnt))
389 return -EFAULT;
390
391 buf[cnt] = 0;
392
393 if (!strncmp(buf, "printf", 6) &&
394 (!buf[6] || isspace(buf[6]))) {
395
396 call->type = TRACE_EVENT_TYPE_PRINTF;
397
398 /*
399 * If raw enabled, the disable it and enable
400 * printf type.
401 */
402 if (call->raw_enabled) {
403 call->raw_enabled = 0;
404 call->raw_unreg();
405
406 call->enabled = 1;
407 call->regfunc();
408 }
409
410 } else if (!strncmp(buf, "raw", 3) &&
411 (!buf[3] || isspace(buf[3]))) {
412
413 call->type = TRACE_EVENT_TYPE_RAW;
414
415 /*
416 * If printf enabled, the disable it and enable
417 * raw type.
418 */
419 if (call->enabled) {
420 call->enabled = 0;
421 call->unregfunc();
422
423 call->raw_enabled = 1;
424 call->raw_reg();
425 }
426 } else
427 return -EINVAL;
428
429 *ppos += cnt;
430
431 return cnt;
432}
433
434static ssize_t
435event_available_types_read(struct file *filp, char __user *ubuf, size_t cnt,
436 loff_t *ppos)
437{
438 struct ftrace_event_call *call = filp->private_data;
439 char buf[16];
440 int r = 0;
441
442 r += sprintf(buf, "printf\n");
443
444 if (call->raw_init)
445 r += sprintf(buf+r, "raw\n");
446
447 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
448}
449
91729ef9
SR
450#undef FIELD
451#define FIELD(type, name) \
452 #type, #name, offsetof(typeof(field), name), sizeof(field.name)
453
454static int trace_write_header(struct trace_seq *s)
455{
456 struct trace_entry field;
457
458 /* struct trace_entry */
459 return trace_seq_printf(s,
460 "\tfield:%s %s;\toffset:%lu;\tsize:%lu;\n"
461 "\tfield:%s %s;\toffset:%lu;\tsize:%lu;\n"
462 "\tfield:%s %s;\toffset:%lu;\tsize:%lu;\n"
463 "\tfield:%s %s;\toffset:%lu;\tsize:%lu;\n"
464 "\tfield:%s %s;\toffset:%lu;\tsize:%lu;\n"
465 "\n",
466 FIELD(unsigned char, type),
467 FIELD(unsigned char, flags),
468 FIELD(unsigned char, preempt_count),
469 FIELD(int, pid),
470 FIELD(int, tgid));
471}
981d081e
SR
472static ssize_t
473event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
474 loff_t *ppos)
475{
476 struct ftrace_event_call *call = filp->private_data;
477 struct trace_seq *s;
478 char *buf;
479 int r;
480
481 s = kmalloc(sizeof(*s), GFP_KERNEL);
482 if (!s)
483 return -ENOMEM;
484
485 trace_seq_init(s);
486
487 if (*ppos)
488 return 0;
489
91729ef9
SR
490 /* If this fails, so will the show_format. */
491 trace_write_header(s);
492
981d081e
SR
493 r = call->show_format(s);
494 if (!r) {
495 /*
496 * ug! The format output is bigger than a PAGE!!
497 */
498 buf = "FORMAT TOO BIG\n";
499 r = simple_read_from_buffer(ubuf, cnt, ppos,
500 buf, strlen(buf));
501 goto out;
502 }
503
504 r = simple_read_from_buffer(ubuf, cnt, ppos,
505 s->buffer, s->len);
506 out:
507 kfree(s);
508 return r;
509}
510
b77e38aa
SR
511static const struct seq_operations show_event_seq_ops = {
512 .start = t_start,
513 .next = t_next,
514 .show = t_show,
515 .stop = t_stop,
516};
517
518static const struct seq_operations show_set_event_seq_ops = {
519 .start = s_start,
520 .next = s_next,
521 .show = t_show,
522 .stop = t_stop,
523};
524
525static const struct file_operations ftrace_avail_fops = {
526 .open = ftrace_event_seq_open,
527 .read = seq_read,
528 .llseek = seq_lseek,
529 .release = seq_release,
530};
531
532static const struct file_operations ftrace_set_event_fops = {
533 .open = ftrace_event_seq_open,
534 .read = seq_read,
535 .write = ftrace_event_write,
536 .llseek = seq_lseek,
537 .release = seq_release,
538};
539
1473e441
SR
540static const struct file_operations ftrace_enable_fops = {
541 .open = tracing_open_generic,
542 .read = event_enable_read,
543 .write = event_enable_write,
544};
545
fd994989
SR
546static const struct file_operations ftrace_type_fops = {
547 .open = tracing_open_generic,
548 .read = event_type_read,
549 .write = event_type_write,
550};
551
552static const struct file_operations ftrace_available_types_fops = {
553 .open = tracing_open_generic,
554 .read = event_available_types_read,
555};
556
981d081e
SR
557static const struct file_operations ftrace_event_format_fops = {
558 .open = tracing_open_generic,
559 .read = event_format_read,
560};
561
1473e441
SR
562static struct dentry *event_trace_events_dir(void)
563{
564 static struct dentry *d_tracer;
565 static struct dentry *d_events;
566
567 if (d_events)
568 return d_events;
569
570 d_tracer = tracing_init_dentry();
571 if (!d_tracer)
572 return NULL;
573
574 d_events = debugfs_create_dir("events", d_tracer);
575 if (!d_events)
576 pr_warning("Could not create debugfs "
577 "'events' directory\n");
578
579 return d_events;
580}
581
6ecc2d1c
SR
582struct event_subsystem {
583 struct list_head list;
584 const char *name;
585 struct dentry *entry;
586};
587
588static LIST_HEAD(event_subsystems);
589
590static struct dentry *
591event_subsystem_dir(const char *name, struct dentry *d_events)
592{
593 struct event_subsystem *system;
594
595 /* First see if we did not already create this dir */
596 list_for_each_entry(system, &event_subsystems, list) {
597 if (strcmp(system->name, name) == 0)
598 return system->entry;
599 }
600
601 /* need to create new entry */
602 system = kmalloc(sizeof(*system), GFP_KERNEL);
603 if (!system) {
604 pr_warning("No memory to create event subsystem %s\n",
605 name);
606 return d_events;
607 }
608
609 system->entry = debugfs_create_dir(name, d_events);
610 if (!system->entry) {
611 pr_warning("Could not create event subsystem %s\n",
612 name);
613 kfree(system);
614 return d_events;
615 }
616
617 system->name = name;
618 list_add(&system->list, &event_subsystems);
619
620 return system->entry;
621}
622
1473e441
SR
623static int
624event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
625{
626 struct dentry *entry;
fd994989 627 int ret;
1473e441 628
6ecc2d1c
SR
629 /*
630 * If the trace point header did not define TRACE_SYSTEM
631 * then the system would be called "TRACE_SYSTEM".
632 */
633 if (strcmp(call->system, "TRACE_SYSTEM") != 0)
634 d_events = event_subsystem_dir(call->system, d_events);
635
fd994989
SR
636 if (call->raw_init) {
637 ret = call->raw_init();
638 if (ret < 0) {
639 pr_warning("Could not initialize trace point"
640 " events/%s\n", call->name);
641 return ret;
642 }
643 }
644
645 /* default the output to printf */
646 call->type = TRACE_EVENT_TYPE_PRINTF;
647
1473e441
SR
648 call->dir = debugfs_create_dir(call->name, d_events);
649 if (!call->dir) {
650 pr_warning("Could not create debugfs "
651 "'%s' directory\n", call->name);
652 return -1;
653 }
654
655 entry = debugfs_create_file("enable", 0644, call->dir, call,
656 &ftrace_enable_fops);
657 if (!entry)
658 pr_warning("Could not create debugfs "
659 "'%s/enable' entry\n", call->name);
660
fd994989
SR
661 /* Only let type be writable, if we can change it */
662 entry = debugfs_create_file("type",
663 call->raw_init ? 0644 : 0444,
664 call->dir, call,
665 &ftrace_type_fops);
666 if (!entry)
667 pr_warning("Could not create debugfs "
668 "'%s/type' entry\n", call->name);
669
670 entry = debugfs_create_file("available_types", 0444, call->dir, call,
671 &ftrace_available_types_fops);
672 if (!entry)
673 pr_warning("Could not create debugfs "
981d081e
SR
674 "'%s/available_types' entry\n", call->name);
675
676 /* A trace may not want to export its format */
677 if (!call->show_format)
678 return 0;
679
680 entry = debugfs_create_file("format", 0444, call->dir, call,
681 &ftrace_event_format_fops);
682 if (!entry)
683 pr_warning("Could not create debugfs "
684 "'%s/format' entry\n", call->name);
fd994989 685
1473e441
SR
686 return 0;
687}
688
b77e38aa
SR
689static __init int event_trace_init(void)
690{
1473e441 691 struct ftrace_event_call *call = __start_ftrace_events;
b77e38aa
SR
692 struct dentry *d_tracer;
693 struct dentry *entry;
1473e441 694 struct dentry *d_events;
b77e38aa
SR
695
696 d_tracer = tracing_init_dentry();
697 if (!d_tracer)
698 return 0;
699
700 entry = debugfs_create_file("available_events", 0444, d_tracer,
701 (void *)&show_event_seq_ops,
702 &ftrace_avail_fops);
703 if (!entry)
704 pr_warning("Could not create debugfs "
705 "'available_events' entry\n");
706
707 entry = debugfs_create_file("set_event", 0644, d_tracer,
708 (void *)&show_set_event_seq_ops,
709 &ftrace_set_event_fops);
710 if (!entry)
711 pr_warning("Could not create debugfs "
712 "'set_event' entry\n");
713
1473e441
SR
714 d_events = event_trace_events_dir();
715 if (!d_events)
716 return 0;
717
718 events_for_each(call) {
719 /* The linker may leave blanks */
720 if (!call->name)
721 continue;
722 event_create_dir(call, d_events);
723 }
724
b77e38aa
SR
725 return 0;
726}
727fs_initcall(event_trace_init);
This page took 0.055557 seconds and 5 git commands to generate.