4 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
8 #include <linux/debugfs.h>
9 #include <linux/uaccess.h>
10 #include <linux/module.h>
11 #include <linux/ctype.h>
13 #include "trace_events.h"
15 void event_trace_printk(unsigned long ip, const char *fmt, ...)
20 tracing_record_cmdline(current);
21 trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap);
25 static void ftrace_clear_events(void)
27 struct ftrace_event_call *call = (void *)__start_ftrace_events;
30 while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
40 static int ftrace_set_clr_event(char *buf, int set)
42 struct ftrace_event_call *call = (void *)__start_ftrace_events;
45 while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
47 if (strcmp(buf, call->name) != 0) {
59 /* Already cleared? */
70 /* 128 should be much more than enough */
71 #define EVENT_BUF_SIZE 127
74 ftrace_event_write(struct file *file, const char __user *ubuf,
75 size_t cnt, loff_t *ppos)
86 ret = get_user(ch, ubuf++);
92 /* skip white space */
93 while (cnt && isspace(ch)) {
94 ret = get_user(ch, ubuf++);
101 /* Only white space found? */
108 buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
112 if (cnt > EVENT_BUF_SIZE)
113 cnt = EVENT_BUF_SIZE;
116 while (cnt && !isspace(ch)) {
122 ret = get_user(ch, ubuf++);
132 ret = ftrace_set_clr_event(buf, set);
145 t_next(struct seq_file *m, void *v, loff_t *pos)
147 struct ftrace_event_call *call = m->private;
148 struct ftrace_event_call *next = call;
152 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
160 static void *t_start(struct seq_file *m, loff_t *pos)
162 return t_next(m, NULL, pos);
166 s_next(struct seq_file *m, void *v, loff_t *pos)
168 struct ftrace_event_call *call = m->private;
169 struct ftrace_event_call *next;
174 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
177 if (!call->enabled) {
188 static void *s_start(struct seq_file *m, loff_t *pos)
190 return s_next(m, NULL, pos);
193 static int t_show(struct seq_file *m, void *v)
195 struct ftrace_event_call *call = v;
197 seq_printf(m, "%s\n", call->name);
202 static void t_stop(struct seq_file *m, void *p)
207 ftrace_event_seq_open(struct inode *inode, struct file *file)
210 const struct seq_operations *seq_ops;
212 if ((file->f_mode & FMODE_WRITE) &&
213 !(file->f_flags & O_APPEND))
214 ftrace_clear_events();
216 seq_ops = inode->i_private;
217 ret = seq_open(file, seq_ops);
219 struct seq_file *m = file->private_data;
221 m->private = __start_ftrace_events;
226 static const struct seq_operations show_event_seq_ops = {
233 static const struct seq_operations show_set_event_seq_ops = {
240 static const struct file_operations ftrace_avail_fops = {
241 .open = ftrace_event_seq_open,
244 .release = seq_release,
247 static const struct file_operations ftrace_set_event_fops = {
248 .open = ftrace_event_seq_open,
250 .write = ftrace_event_write,
252 .release = seq_release,
255 static __init int event_trace_init(void)
257 struct dentry *d_tracer;
258 struct dentry *entry;
260 d_tracer = tracing_init_dentry();
264 entry = debugfs_create_file("available_events", 0444, d_tracer,
265 (void *)&show_event_seq_ops,
268 pr_warning("Could not create debugfs "
269 "'available_events' entry\n");
271 entry = debugfs_create_file("set_event", 0644, d_tracer,
272 (void *)&show_set_event_seq_ops,
273 &ftrace_set_event_fops);
275 pr_warning("Could not create debugfs "
276 "'set_event' entry\n");
280 fs_initcall(event_trace_init);