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