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