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