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