blob: 210e71ff82db800bf95a2438905061b1cc7616e6 [file] [log] [blame]
Steven Rostedtb77e38a2009-02-24 10:21:36 -05001/*
2 * event tracer
3 *
4 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5 *
Steven Rostedt981d0812009-03-02 13:53:59 -05006 * - Added format output of fields of the trace point.
7 * This was based off of work by Tom Zanussi <tzanussi@gmail.com>.
8 *
Steven Rostedtb77e38a2009-02-24 10:21:36 -05009 */
10
11#include <linux/debugfs.h>
12#include <linux/uaccess.h>
13#include <linux/module.h>
14#include <linux/ctype.h>
15
Steven Rostedt91729ef92009-03-02 15:03:01 -050016#include "trace_output.h"
Steven Rostedtb77e38a2009-02-24 10:21:36 -050017
Steven Rostedtb628b3e2009-02-27 23:32:58 -050018#define TRACE_SYSTEM "TRACE_SYSTEM"
19
Steven Rostedt11a241a2009-03-02 11:49:04 -050020static DEFINE_MUTEX(event_mutex);
21
Steven Rostedt1473e442009-02-24 14:15:08 -050022#define events_for_each(event) \
23 for (event = __start_ftrace_events; \
24 (unsigned long)event < (unsigned long)__stop_ftrace_events; \
25 event++)
26
Steven Rostedtb77e38a2009-02-24 10:21:36 -050027void 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
Steven Rostedtfd994982009-02-28 02:41:25 -050052static 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
Steven Rostedtb77e38a2009-02-24 10:21:36 -050082static int ftrace_set_clr_event(char *buf, int set)
83{
Steven Rostedt1473e442009-02-24 14:15:08 -050084 struct ftrace_event_call *call = __start_ftrace_events;
Steven Rostedtb628b3e2009-02-27 23:32:58 -050085 char *event = NULL, *sub = NULL, *match;
86 int ret = -EINVAL;
Steven Rostedtb77e38a2009-02-24 10:21:36 -050087
Steven Rostedtb628b3e2009-02-27 23:32:58 -050088 /*
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 }
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500111
Steven Rostedt11a241a2009-03-02 11:49:04 -0500112 mutex_lock(&event_mutex);
Steven Rostedt1473e442009-02-24 14:15:08 -0500113 events_for_each(call) {
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500114
Steven Rostedt1473e442009-02-24 14:15:08 -0500115 if (!call->name)
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500116 continue;
Steven Rostedt1473e442009-02-24 14:15:08 -0500117
Steven Rostedtb628b3e2009-02-27 23:32:58 -0500118 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)
Steven Rostedt1473e442009-02-24 14:15:08 -0500127 continue;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500128
Steven Rostedtfd994982009-02-28 02:41:25 -0500129 ftrace_event_enable_disable(call, set);
130
Steven Rostedtb628b3e2009-02-27 23:32:58 -0500131 ret = 0;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500132 }
Steven Rostedt11a241a2009-03-02 11:49:04 -0500133 mutex_unlock(&event_mutex);
134
Steven Rostedtb628b3e2009-02-27 23:32:58 -0500135 return ret;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500136}
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
Steven Rostedtb628b3e2009-02-27 23:32:58 -0500265 if (strcmp(call->system, TRACE_SYSTEM) != 0)
266 seq_printf(m, "%s:", call->system);
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500267 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
Steven Rostedt1473e442009-02-24 14:15:08 -0500296static 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
Steven Rostedtfd994982009-02-28 02:41:25 -0500303 if (call->enabled || call->raw_enabled)
Steven Rostedt1473e442009-02-24 14:15:08 -0500304 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:
Steven Rostedt1473e442009-02-24 14:15:08 -0500334 case 1:
Steven Rostedt11a241a2009-03-02 11:49:04 -0500335 mutex_lock(&event_mutex);
Steven Rostedtfd994982009-02-28 02:41:25 -0500336 ftrace_event_enable_disable(call, val);
Steven Rostedt11a241a2009-03-02 11:49:04 -0500337 mutex_unlock(&event_mutex);
Steven Rostedt1473e442009-02-24 14:15:08 -0500338 break;
339
340 default:
341 return -EINVAL;
342 }
343
344 *ppos += cnt;
345
346 return cnt;
347}
348
Steven Rostedtfd994982009-02-28 02:41:25 -0500349static 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
Steven Rostedt91729ef92009-03-02 15:03:01 -0500450#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}
Steven Rostedt981d0812009-03-02 13:53:59 -0500472static 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
Steven Rostedtc5e4e192009-03-02 15:10:02 -0500490 /* If any of the first writes fail, so will the show_format. */
491
492 trace_seq_printf(s, "name: %s\n", call->name);
493 trace_seq_printf(s, "ID: %d\n", call->id);
494 trace_seq_printf(s, "format:\n");
Steven Rostedt91729ef92009-03-02 15:03:01 -0500495 trace_write_header(s);
496
Steven Rostedt981d0812009-03-02 13:53:59 -0500497 r = call->show_format(s);
498 if (!r) {
499 /*
500 * ug! The format output is bigger than a PAGE!!
501 */
502 buf = "FORMAT TOO BIG\n";
503 r = simple_read_from_buffer(ubuf, cnt, ppos,
504 buf, strlen(buf));
505 goto out;
506 }
507
508 r = simple_read_from_buffer(ubuf, cnt, ppos,
509 s->buffer, s->len);
510 out:
511 kfree(s);
512 return r;
513}
514
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500515static const struct seq_operations show_event_seq_ops = {
516 .start = t_start,
517 .next = t_next,
518 .show = t_show,
519 .stop = t_stop,
520};
521
522static const struct seq_operations show_set_event_seq_ops = {
523 .start = s_start,
524 .next = s_next,
525 .show = t_show,
526 .stop = t_stop,
527};
528
529static const struct file_operations ftrace_avail_fops = {
530 .open = ftrace_event_seq_open,
531 .read = seq_read,
532 .llseek = seq_lseek,
533 .release = seq_release,
534};
535
536static const struct file_operations ftrace_set_event_fops = {
537 .open = ftrace_event_seq_open,
538 .read = seq_read,
539 .write = ftrace_event_write,
540 .llseek = seq_lseek,
541 .release = seq_release,
542};
543
Steven Rostedt1473e442009-02-24 14:15:08 -0500544static const struct file_operations ftrace_enable_fops = {
545 .open = tracing_open_generic,
546 .read = event_enable_read,
547 .write = event_enable_write,
548};
549
Steven Rostedtfd994982009-02-28 02:41:25 -0500550static const struct file_operations ftrace_type_fops = {
551 .open = tracing_open_generic,
552 .read = event_type_read,
553 .write = event_type_write,
554};
555
556static const struct file_operations ftrace_available_types_fops = {
557 .open = tracing_open_generic,
558 .read = event_available_types_read,
559};
560
Steven Rostedt981d0812009-03-02 13:53:59 -0500561static const struct file_operations ftrace_event_format_fops = {
562 .open = tracing_open_generic,
563 .read = event_format_read,
564};
565
Steven Rostedt1473e442009-02-24 14:15:08 -0500566static struct dentry *event_trace_events_dir(void)
567{
568 static struct dentry *d_tracer;
569 static struct dentry *d_events;
570
571 if (d_events)
572 return d_events;
573
574 d_tracer = tracing_init_dentry();
575 if (!d_tracer)
576 return NULL;
577
578 d_events = debugfs_create_dir("events", d_tracer);
579 if (!d_events)
580 pr_warning("Could not create debugfs "
581 "'events' directory\n");
582
583 return d_events;
584}
585
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500586struct event_subsystem {
587 struct list_head list;
588 const char *name;
589 struct dentry *entry;
590};
591
592static LIST_HEAD(event_subsystems);
593
594static struct dentry *
595event_subsystem_dir(const char *name, struct dentry *d_events)
596{
597 struct event_subsystem *system;
598
599 /* First see if we did not already create this dir */
600 list_for_each_entry(system, &event_subsystems, list) {
601 if (strcmp(system->name, name) == 0)
602 return system->entry;
603 }
604
605 /* need to create new entry */
606 system = kmalloc(sizeof(*system), GFP_KERNEL);
607 if (!system) {
608 pr_warning("No memory to create event subsystem %s\n",
609 name);
610 return d_events;
611 }
612
613 system->entry = debugfs_create_dir(name, d_events);
614 if (!system->entry) {
615 pr_warning("Could not create event subsystem %s\n",
616 name);
617 kfree(system);
618 return d_events;
619 }
620
621 system->name = name;
622 list_add(&system->list, &event_subsystems);
623
624 return system->entry;
625}
626
Steven Rostedt1473e442009-02-24 14:15:08 -0500627static int
628event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
629{
630 struct dentry *entry;
Steven Rostedtfd994982009-02-28 02:41:25 -0500631 int ret;
Steven Rostedt1473e442009-02-24 14:15:08 -0500632
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500633 /*
634 * If the trace point header did not define TRACE_SYSTEM
635 * then the system would be called "TRACE_SYSTEM".
636 */
637 if (strcmp(call->system, "TRACE_SYSTEM") != 0)
638 d_events = event_subsystem_dir(call->system, d_events);
639
Steven Rostedtfd994982009-02-28 02:41:25 -0500640 if (call->raw_init) {
641 ret = call->raw_init();
642 if (ret < 0) {
643 pr_warning("Could not initialize trace point"
644 " events/%s\n", call->name);
645 return ret;
646 }
647 }
648
649 /* default the output to printf */
650 call->type = TRACE_EVENT_TYPE_PRINTF;
651
Steven Rostedt1473e442009-02-24 14:15:08 -0500652 call->dir = debugfs_create_dir(call->name, d_events);
653 if (!call->dir) {
654 pr_warning("Could not create debugfs "
655 "'%s' directory\n", call->name);
656 return -1;
657 }
658
659 entry = debugfs_create_file("enable", 0644, call->dir, call,
660 &ftrace_enable_fops);
661 if (!entry)
662 pr_warning("Could not create debugfs "
663 "'%s/enable' entry\n", call->name);
664
Steven Rostedtfd994982009-02-28 02:41:25 -0500665 /* Only let type be writable, if we can change it */
666 entry = debugfs_create_file("type",
667 call->raw_init ? 0644 : 0444,
668 call->dir, call,
669 &ftrace_type_fops);
670 if (!entry)
671 pr_warning("Could not create debugfs "
672 "'%s/type' entry\n", call->name);
673
674 entry = debugfs_create_file("available_types", 0444, call->dir, call,
675 &ftrace_available_types_fops);
676 if (!entry)
677 pr_warning("Could not create debugfs "
Steven Rostedt981d0812009-03-02 13:53:59 -0500678 "'%s/available_types' entry\n", call->name);
679
680 /* A trace may not want to export its format */
681 if (!call->show_format)
682 return 0;
683
684 entry = debugfs_create_file("format", 0444, call->dir, call,
685 &ftrace_event_format_fops);
686 if (!entry)
687 pr_warning("Could not create debugfs "
688 "'%s/format' entry\n", call->name);
Steven Rostedtfd994982009-02-28 02:41:25 -0500689
Steven Rostedt1473e442009-02-24 14:15:08 -0500690 return 0;
691}
692
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500693static __init int event_trace_init(void)
694{
Steven Rostedt1473e442009-02-24 14:15:08 -0500695 struct ftrace_event_call *call = __start_ftrace_events;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500696 struct dentry *d_tracer;
697 struct dentry *entry;
Steven Rostedt1473e442009-02-24 14:15:08 -0500698 struct dentry *d_events;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500699
700 d_tracer = tracing_init_dentry();
701 if (!d_tracer)
702 return 0;
703
704 entry = debugfs_create_file("available_events", 0444, d_tracer,
705 (void *)&show_event_seq_ops,
706 &ftrace_avail_fops);
707 if (!entry)
708 pr_warning("Could not create debugfs "
709 "'available_events' entry\n");
710
711 entry = debugfs_create_file("set_event", 0644, d_tracer,
712 (void *)&show_set_event_seq_ops,
713 &ftrace_set_event_fops);
714 if (!entry)
715 pr_warning("Could not create debugfs "
716 "'set_event' entry\n");
717
Steven Rostedt1473e442009-02-24 14:15:08 -0500718 d_events = event_trace_events_dir();
719 if (!d_events)
720 return 0;
721
722 events_for_each(call) {
723 /* The linker may leave blanks */
724 if (!call->name)
725 continue;
726 event_create_dir(call, d_events);
727 }
728
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500729 return 0;
730}
731fs_initcall(event_trace_init);