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 #define events_for_each(event) \
23 for (event = __start_ftrace_events; \
24 (unsigned long)event < (unsigned long)__stop_ftrace_events; \
27 void event_trace_printk(unsigned long ip, const char *fmt, ...)
32 tracing_record_cmdline(current);
33 trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap);
37 static void ftrace_clear_events(void)
39 struct ftrace_event_call *call = (void *)__start_ftrace_events;
42 while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
52 static void ftrace_event_enable_disable(struct ftrace_event_call *call,
72 static int ftrace_set_clr_event(char *buf, int set)
74 struct ftrace_event_call *call = __start_ftrace_events;
75 char *event = NULL, *sub = NULL, *match;
79 * The buf format can be <subsystem>:<event-name>
80 * *:<event-name> means any event by that name.
81 * :<event-name> is the same.
83 * <subsystem>:* means all events in that subsystem
84 * <subsystem>: means the same.
86 * <name> (no ':') means all events in a subsystem with
87 * the name <name> or any event that matches <name>
90 match = strsep(&buf, ":");
96 if (!strlen(sub) || strcmp(sub, "*") == 0)
98 if (!strlen(event) || strcmp(event, "*") == 0)
102 mutex_lock(&event_mutex);
103 events_for_each(call) {
105 if (!call->name || !call->regfunc)
109 strcmp(match, call->name) != 0 &&
110 strcmp(match, call->system) != 0)
113 if (sub && strcmp(sub, call->system) != 0)
116 if (event && strcmp(event, call->name) != 0)
119 ftrace_event_enable_disable(call, set);
123 mutex_unlock(&event_mutex);
128 /* 128 should be much more than enough */
129 #define EVENT_BUF_SIZE 127
132 ftrace_event_write(struct file *file, const char __user *ubuf,
133 size_t cnt, loff_t *ppos)
144 ret = tracing_update_buffers();
148 ret = get_user(ch, ubuf++);
154 /* skip white space */
155 while (cnt && isspace(ch)) {
156 ret = get_user(ch, ubuf++);
163 /* Only white space found? */
170 buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
174 if (cnt > EVENT_BUF_SIZE)
175 cnt = EVENT_BUF_SIZE;
178 while (cnt && !isspace(ch)) {
184 ret = get_user(ch, ubuf++);
194 ret = ftrace_set_clr_event(buf, set);
207 t_next(struct seq_file *m, void *v, loff_t *pos)
209 struct ftrace_event_call *call = m->private;
210 struct ftrace_event_call *next = call;
215 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
219 * The ftrace subsystem is for showing formats only.
220 * They can not be enabled or disabled via the event files.
234 static void *t_start(struct seq_file *m, loff_t *pos)
236 return t_next(m, NULL, pos);
240 s_next(struct seq_file *m, void *v, loff_t *pos)
242 struct ftrace_event_call *call = m->private;
243 struct ftrace_event_call *next;
248 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
251 if (!call->enabled) {
262 static void *s_start(struct seq_file *m, loff_t *pos)
264 return s_next(m, NULL, pos);
267 static int t_show(struct seq_file *m, void *v)
269 struct ftrace_event_call *call = v;
271 if (strcmp(call->system, TRACE_SYSTEM) != 0)
272 seq_printf(m, "%s:", call->system);
273 seq_printf(m, "%s\n", call->name);
278 static void t_stop(struct seq_file *m, void *p)
283 ftrace_event_seq_open(struct inode *inode, struct file *file)
286 const struct seq_operations *seq_ops;
288 if ((file->f_mode & FMODE_WRITE) &&
289 !(file->f_flags & O_APPEND))
290 ftrace_clear_events();
292 seq_ops = inode->i_private;
293 ret = seq_open(file, seq_ops);
295 struct seq_file *m = file->private_data;
297 m->private = __start_ftrace_events;
303 event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
306 struct ftrace_event_call *call = filp->private_data;
314 return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
318 event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
321 struct ftrace_event_call *call = filp->private_data;
326 if (cnt >= sizeof(buf))
329 if (copy_from_user(&buf, ubuf, cnt))
334 ret = strict_strtoul(buf, 10, &val);
338 ret = tracing_update_buffers();
345 mutex_lock(&event_mutex);
346 ftrace_event_enable_disable(call, val);
347 mutex_unlock(&event_mutex);
360 #define FIELD(type, name) \
361 #type, #name, offsetof(typeof(field), name), sizeof(field.name)
363 static int trace_write_header(struct trace_seq *s)
365 struct trace_entry field;
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"
375 FIELD(unsigned char, type),
376 FIELD(unsigned char, flags),
377 FIELD(unsigned char, preempt_count),
383 event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
386 struct ftrace_event_call *call = filp->private_data;
391 s = kmalloc(sizeof(*s), GFP_KERNEL);
400 /* If any of the first writes fail, so will the show_format. */
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);
407 r = call->show_format(s);
410 * ug! The format output is bigger than a PAGE!!
412 buf = "FORMAT TOO BIG\n";
413 r = simple_read_from_buffer(ubuf, cnt, ppos,
418 r = simple_read_from_buffer(ubuf, cnt, ppos,
425 static const struct seq_operations show_event_seq_ops = {
432 static const struct seq_operations show_set_event_seq_ops = {
439 static const struct file_operations ftrace_avail_fops = {
440 .open = ftrace_event_seq_open,
443 .release = seq_release,
446 static const struct file_operations ftrace_set_event_fops = {
447 .open = ftrace_event_seq_open,
449 .write = ftrace_event_write,
451 .release = seq_release,
454 static const struct file_operations ftrace_enable_fops = {
455 .open = tracing_open_generic,
456 .read = event_enable_read,
457 .write = event_enable_write,
460 static const struct file_operations ftrace_event_format_fops = {
461 .open = tracing_open_generic,
462 .read = event_format_read,
465 static struct dentry *event_trace_events_dir(void)
467 static struct dentry *d_tracer;
468 static struct dentry *d_events;
473 d_tracer = tracing_init_dentry();
477 d_events = debugfs_create_dir("events", d_tracer);
479 pr_warning("Could not create debugfs "
480 "'events' directory\n");
485 struct event_subsystem {
486 struct list_head list;
488 struct dentry *entry;
491 static LIST_HEAD(event_subsystems);
493 static struct dentry *
494 event_subsystem_dir(const char *name, struct dentry *d_events)
496 struct event_subsystem *system;
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;
504 /* need to create new entry */
505 system = kmalloc(sizeof(*system), GFP_KERNEL);
507 pr_warning("No memory to create event subsystem %s\n",
512 system->entry = debugfs_create_dir(name, d_events);
513 if (!system->entry) {
514 pr_warning("Could not create event subsystem %s\n",
521 list_add(&system->list, &event_subsystems);
523 return system->entry;
527 event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
529 struct dentry *entry;
533 * If the trace point header did not define TRACE_SYSTEM
534 * then the system would be called "TRACE_SYSTEM".
536 if (strcmp(call->system, "TRACE_SYSTEM") != 0)
537 d_events = event_subsystem_dir(call->system, d_events);
539 if (call->raw_init) {
540 ret = call->raw_init();
542 pr_warning("Could not initialize trace point"
543 " events/%s\n", call->name);
548 call->dir = debugfs_create_dir(call->name, d_events);
550 pr_warning("Could not create debugfs "
551 "'%s' directory\n", call->name);
556 entry = debugfs_create_file("enable", 0644, call->dir, call,
557 &ftrace_enable_fops);
559 pr_warning("Could not create debugfs "
560 "'%s/enable' entry\n", call->name);
563 /* A trace may not want to export its format */
564 if (!call->show_format)
567 entry = debugfs_create_file("format", 0444, call->dir, call,
568 &ftrace_event_format_fops);
570 pr_warning("Could not create debugfs "
571 "'%s/format' entry\n", call->name);
576 static __init int event_trace_init(void)
578 struct ftrace_event_call *call = __start_ftrace_events;
579 struct dentry *d_tracer;
580 struct dentry *entry;
581 struct dentry *d_events;
583 d_tracer = tracing_init_dentry();
587 entry = debugfs_create_file("available_events", 0444, d_tracer,
588 (void *)&show_event_seq_ops,
591 pr_warning("Could not create debugfs "
592 "'available_events' entry\n");
594 entry = debugfs_create_file("set_event", 0644, d_tracer,
595 (void *)&show_set_event_seq_ops,
596 &ftrace_set_event_fops);
598 pr_warning("Could not create debugfs "
599 "'set_event' entry\n");
601 d_events = event_trace_events_dir();
605 events_for_each(call) {
606 /* The linker may leave blanks */
609 event_create_dir(call, d_events);
614 fs_initcall(event_trace_init);