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