4 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
6 * - Added format output of fields of the trace point.
7 * This was based off of work by Tom Zanussi <tzanussi@gmail.com>.
11 #include <linux/debugfs.h>
12 #include <linux/uaccess.h>
13 #include <linux/module.h>
14 #include <linux/ctype.h>
16 #include "trace_output.h"
18 #define TRACE_SYSTEM "TRACE_SYSTEM"
20 static DEFINE_MUTEX(event_mutex);
22 static void ftrace_clear_events(void)
24 struct ftrace_event_call *call = (void *)__start_ftrace_events;
27 while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
37 static void ftrace_event_enable_disable(struct ftrace_event_call *call,
57 static int ftrace_set_clr_event(char *buf, int set)
59 struct ftrace_event_call *call = __start_ftrace_events;
60 char *event = NULL, *sub = NULL, *match;
64 * The buf format can be <subsystem>:<event-name>
65 * *:<event-name> means any event by that name.
66 * :<event-name> is the same.
68 * <subsystem>:* means all events in that subsystem
69 * <subsystem>: means the same.
71 * <name> (no ':') means all events in a subsystem with
72 * the name <name> or any event that matches <name>
75 match = strsep(&buf, ":");
81 if (!strlen(sub) || strcmp(sub, "*") == 0)
83 if (!strlen(event) || strcmp(event, "*") == 0)
87 mutex_lock(&event_mutex);
88 for_each_event(call) {
90 if (!call->name || !call->regfunc)
94 strcmp(match, call->name) != 0 &&
95 strcmp(match, call->system) != 0)
98 if (sub && strcmp(sub, call->system) != 0)
101 if (event && strcmp(event, call->name) != 0)
104 ftrace_event_enable_disable(call, set);
108 mutex_unlock(&event_mutex);
113 /* 128 should be much more than enough */
114 #define EVENT_BUF_SIZE 127
117 ftrace_event_write(struct file *file, const char __user *ubuf,
118 size_t cnt, loff_t *ppos)
129 ret = tracing_update_buffers();
133 ret = get_user(ch, ubuf++);
139 /* skip white space */
140 while (cnt && isspace(ch)) {
141 ret = get_user(ch, ubuf++);
148 /* Only white space found? */
155 buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
159 if (cnt > EVENT_BUF_SIZE)
160 cnt = EVENT_BUF_SIZE;
163 while (cnt && !isspace(ch)) {
169 ret = get_user(ch, ubuf++);
179 ret = ftrace_set_clr_event(buf, set);
192 t_next(struct seq_file *m, void *v, loff_t *pos)
194 struct ftrace_event_call *call = m->private;
195 struct ftrace_event_call *next = call;
200 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
204 * The ftrace subsystem is for showing formats only.
205 * They can not be enabled or disabled via the event files.
219 static void *t_start(struct seq_file *m, loff_t *pos)
221 return t_next(m, NULL, pos);
225 s_next(struct seq_file *m, void *v, loff_t *pos)
227 struct ftrace_event_call *call = m->private;
228 struct ftrace_event_call *next;
233 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
236 if (!call->enabled) {
247 static void *s_start(struct seq_file *m, loff_t *pos)
249 return s_next(m, NULL, pos);
252 static int t_show(struct seq_file *m, void *v)
254 struct ftrace_event_call *call = v;
256 if (strcmp(call->system, TRACE_SYSTEM) != 0)
257 seq_printf(m, "%s:", call->system);
258 seq_printf(m, "%s\n", call->name);
263 static void t_stop(struct seq_file *m, void *p)
268 ftrace_event_seq_open(struct inode *inode, struct file *file)
271 const struct seq_operations *seq_ops;
273 if ((file->f_mode & FMODE_WRITE) &&
274 !(file->f_flags & O_APPEND))
275 ftrace_clear_events();
277 seq_ops = inode->i_private;
278 ret = seq_open(file, seq_ops);
280 struct seq_file *m = file->private_data;
282 m->private = __start_ftrace_events;
288 event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
291 struct ftrace_event_call *call = filp->private_data;
299 return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
303 event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
306 struct ftrace_event_call *call = filp->private_data;
311 if (cnt >= sizeof(buf))
314 if (copy_from_user(&buf, ubuf, cnt))
319 ret = strict_strtoul(buf, 10, &val);
323 ret = tracing_update_buffers();
330 mutex_lock(&event_mutex);
331 ftrace_event_enable_disable(call, val);
332 mutex_unlock(&event_mutex);
345 #define FIELD(type, name) \
346 #type, #name, offsetof(typeof(field), name), sizeof(field.name)
348 static int trace_write_header(struct trace_seq *s)
350 struct trace_entry field;
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"
360 FIELD(unsigned char, type),
361 FIELD(unsigned char, flags),
362 FIELD(unsigned char, preempt_count),
368 event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
371 struct ftrace_event_call *call = filp->private_data;
379 s = kmalloc(sizeof(*s), GFP_KERNEL);
385 /* If any of the first writes fail, so will the show_format. */
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);
392 r = call->show_format(s);
395 * ug! The format output is bigger than a PAGE!!
397 buf = "FORMAT TOO BIG\n";
398 r = simple_read_from_buffer(ubuf, cnt, ppos,
403 r = simple_read_from_buffer(ubuf, cnt, ppos,
411 event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
413 struct ftrace_event_call *call = filp->private_data;
420 s = kmalloc(sizeof(*s), GFP_KERNEL);
425 trace_seq_printf(s, "%d\n", call->id);
427 r = simple_read_from_buffer(ubuf, cnt, ppos,
433 static const struct seq_operations show_event_seq_ops = {
440 static const struct seq_operations show_set_event_seq_ops = {
447 static const struct file_operations ftrace_avail_fops = {
448 .open = ftrace_event_seq_open,
451 .release = seq_release,
454 static const struct file_operations ftrace_set_event_fops = {
455 .open = ftrace_event_seq_open,
457 .write = ftrace_event_write,
459 .release = seq_release,
462 static const struct file_operations ftrace_enable_fops = {
463 .open = tracing_open_generic,
464 .read = event_enable_read,
465 .write = event_enable_write,
468 static const struct file_operations ftrace_event_format_fops = {
469 .open = tracing_open_generic,
470 .read = event_format_read,
473 static const struct file_operations ftrace_event_id_fops = {
474 .open = tracing_open_generic,
475 .read = event_id_read,
478 static struct dentry *event_trace_events_dir(void)
480 static struct dentry *d_tracer;
481 static struct dentry *d_events;
486 d_tracer = tracing_init_dentry();
490 d_events = debugfs_create_dir("events", d_tracer);
492 pr_warning("Could not create debugfs "
493 "'events' directory\n");
498 struct event_subsystem {
499 struct list_head list;
501 struct dentry *entry;
504 static LIST_HEAD(event_subsystems);
506 static struct dentry *
507 event_subsystem_dir(const char *name, struct dentry *d_events)
509 struct event_subsystem *system;
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;
517 /* need to create new entry */
518 system = kmalloc(sizeof(*system), GFP_KERNEL);
520 pr_warning("No memory to create event subsystem %s\n",
525 system->entry = debugfs_create_dir(name, d_events);
526 if (!system->entry) {
527 pr_warning("Could not create event subsystem %s\n",
534 list_add(&system->list, &event_subsystems);
536 return system->entry;
540 event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
542 struct dentry *entry;
546 * If the trace point header did not define TRACE_SYSTEM
547 * then the system would be called "TRACE_SYSTEM".
549 if (strcmp(call->system, "TRACE_SYSTEM") != 0)
550 d_events = event_subsystem_dir(call->system, d_events);
552 if (call->raw_init) {
553 ret = call->raw_init();
555 pr_warning("Could not initialize trace point"
556 " events/%s\n", call->name);
561 call->dir = debugfs_create_dir(call->name, d_events);
563 pr_warning("Could not create debugfs "
564 "'%s' directory\n", call->name);
569 entry = debugfs_create_file("enable", 0644, call->dir, call,
570 &ftrace_enable_fops);
572 pr_warning("Could not create debugfs "
573 "'%s/enable' entry\n", call->name);
577 entry = debugfs_create_file("id", 0444, call->dir, call,
578 &ftrace_event_id_fops);
580 pr_warning("Could not create debugfs '%s/id' entry\n",
584 /* A trace may not want to export its format */
585 if (!call->show_format)
588 entry = debugfs_create_file("format", 0444, call->dir, call,
589 &ftrace_event_format_fops);
591 pr_warning("Could not create debugfs "
592 "'%s/format' entry\n", call->name);
597 static __init int event_trace_init(void)
599 struct ftrace_event_call *call = __start_ftrace_events;
600 struct dentry *d_tracer;
601 struct dentry *entry;
602 struct dentry *d_events;
604 d_tracer = tracing_init_dentry();
608 entry = debugfs_create_file("available_events", 0444, d_tracer,
609 (void *)&show_event_seq_ops,
612 pr_warning("Could not create debugfs "
613 "'available_events' entry\n");
615 entry = debugfs_create_file("set_event", 0644, d_tracer,
616 (void *)&show_set_event_seq_ops,
617 &ftrace_set_event_fops);
619 pr_warning("Could not create debugfs "
620 "'set_event' entry\n");
622 d_events = event_trace_events_dir();
626 for_each_event(call) {
627 /* The linker may leave blanks */
630 event_create_dir(call, d_events);
635 fs_initcall(event_trace_init);