blob: 79d352027a6194759c6477e64b5390b1a5da2822 [file] [log] [blame]
Steven Rostedtb77e38a2009-02-24 10:21:36 -05001/*
2 * event tracer
3 *
4 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5 *
Steven Rostedt981d0812009-03-02 13:53:59 -05006 * - Added format output of fields of the trace point.
7 * This was based off of work by Tom Zanussi <tzanussi@gmail.com>.
8 *
Steven Rostedtb77e38a2009-02-24 10:21:36 -05009 */
10
Steven Rostedte6187002009-04-15 13:36:40 -040011#include <linux/workqueue.h>
12#include <linux/spinlock.h>
13#include <linux/kthread.h>
Steven Rostedtb77e38a2009-02-24 10:21:36 -050014#include <linux/debugfs.h>
15#include <linux/uaccess.h>
16#include <linux/module.h>
17#include <linux/ctype.h>
Steven Rostedte6187002009-04-15 13:36:40 -040018#include <linux/delay.h>
Steven Rostedtb77e38a2009-02-24 10:21:36 -050019
Li Zefan020e5f82009-07-01 10:47:05 +080020#include <asm/setup.h>
21
Steven Rostedt91729ef2009-03-02 15:03:01 -050022#include "trace_output.h"
Steven Rostedtb77e38a2009-02-24 10:21:36 -050023
Steven Rostedtb628b3e2009-02-27 23:32:58 -050024#define TRACE_SYSTEM "TRACE_SYSTEM"
25
Li Zefan20c89282009-05-06 10:33:45 +080026DEFINE_MUTEX(event_mutex);
Steven Rostedt11a241a2009-03-02 11:49:04 -050027
Steven Rostedta59fd602009-04-10 13:52:20 -040028LIST_HEAD(ftrace_events);
29
Li Zefan540b7b82009-08-19 15:54:51 +080030int trace_define_field(struct ftrace_event_call *call, const char *type,
31 const char *name, int offset, int size, int is_signed)
Tom Zanussicf027f62009-03-22 03:30:39 -050032{
33 struct ftrace_event_field *field;
34
Ingo Molnarfe9f57f2009-03-22 18:41:59 +010035 field = kzalloc(sizeof(*field), GFP_KERNEL);
Tom Zanussicf027f62009-03-22 03:30:39 -050036 if (!field)
37 goto err;
Ingo Molnarfe9f57f2009-03-22 18:41:59 +010038
Tom Zanussicf027f62009-03-22 03:30:39 -050039 field->name = kstrdup(name, GFP_KERNEL);
40 if (!field->name)
41 goto err;
Ingo Molnarfe9f57f2009-03-22 18:41:59 +010042
Tom Zanussicf027f62009-03-22 03:30:39 -050043 field->type = kstrdup(type, GFP_KERNEL);
44 if (!field->type)
45 goto err;
Ingo Molnarfe9f57f2009-03-22 18:41:59 +010046
Tom Zanussicf027f62009-03-22 03:30:39 -050047 field->offset = offset;
48 field->size = size;
Tom Zanussia118e4d2009-04-28 03:04:53 -050049 field->is_signed = is_signed;
Tom Zanussicf027f62009-03-22 03:30:39 -050050 list_add(&field->link, &call->fields);
51
52 return 0;
Ingo Molnarfe9f57f2009-03-22 18:41:59 +010053
Tom Zanussicf027f62009-03-22 03:30:39 -050054err:
55 if (field) {
56 kfree(field->name);
57 kfree(field->type);
58 }
59 kfree(field);
Ingo Molnarfe9f57f2009-03-22 18:41:59 +010060
Tom Zanussicf027f62009-03-22 03:30:39 -050061 return -ENOMEM;
62}
Steven Rostedt17c873e2009-04-10 18:12:50 -040063EXPORT_SYMBOL_GPL(trace_define_field);
Tom Zanussicf027f62009-03-22 03:30:39 -050064
Li Zefane647d6b2009-08-19 15:54:32 +080065#define __common_field(type, item) \
66 ret = trace_define_field(call, #type, "common_" #item, \
67 offsetof(typeof(ent), item), \
68 sizeof(ent.item), \
69 is_signed_type(type)); \
70 if (ret) \
71 return ret;
72
73int trace_define_common_fields(struct ftrace_event_call *call)
74{
75 int ret;
76 struct trace_entry ent;
77
78 __common_field(unsigned short, type);
79 __common_field(unsigned char, flags);
80 __common_field(unsigned char, preempt_count);
81 __common_field(int, pid);
82 __common_field(int, tgid);
83
84 return ret;
85}
Li Zefan540b7b82009-08-19 15:54:51 +080086EXPORT_SYMBOL_GPL(trace_define_common_fields);
Li Zefane647d6b2009-08-19 15:54:32 +080087
Li Zefan2df75e42009-05-06 10:33:04 +080088#ifdef CONFIG_MODULES
89
90static void trace_destroy_fields(struct ftrace_event_call *call)
91{
92 struct ftrace_event_field *field, *next;
93
94 list_for_each_entry_safe(field, next, &call->fields, link) {
95 list_del(&field->link);
96 kfree(field->type);
97 kfree(field->name);
98 kfree(field);
99 }
100}
101
102#endif /* CONFIG_MODULES */
103
Steven Rostedtfd994982009-02-28 02:41:25 -0500104static void ftrace_event_enable_disable(struct ftrace_event_call *call,
105 int enable)
106{
Steven Rostedtfd994982009-02-28 02:41:25 -0500107 switch (enable) {
108 case 0:
109 if (call->enabled) {
110 call->enabled = 0;
Zhaoleib11c53e2009-05-25 18:11:59 +0800111 tracing_stop_cmdline_record();
Jason Baron69fd4f02009-08-10 16:52:44 -0400112 call->unregfunc(call->data);
Steven Rostedtfd994982009-02-28 02:41:25 -0500113 }
Steven Rostedtfd994982009-02-28 02:41:25 -0500114 break;
115 case 1:
Steven Rostedtda4d0302009-03-09 17:14:30 -0400116 if (!call->enabled) {
Steven Rostedtfd994982009-02-28 02:41:25 -0500117 call->enabled = 1;
Zhaoleib11c53e2009-05-25 18:11:59 +0800118 tracing_start_cmdline_record();
Jason Baron69fd4f02009-08-10 16:52:44 -0400119 call->regfunc(call->data);
Steven Rostedtfd994982009-02-28 02:41:25 -0500120 }
Steven Rostedtfd994982009-02-28 02:41:25 -0500121 break;
122 }
123}
124
Zhaolei0e907c92009-05-25 18:13:59 +0800125static void ftrace_clear_events(void)
126{
127 struct ftrace_event_call *call;
128
129 mutex_lock(&event_mutex);
130 list_for_each_entry(call, &ftrace_events, list) {
131 ftrace_event_enable_disable(call, 0);
132 }
133 mutex_unlock(&event_mutex);
134}
135
Li Zefan8f31bfe2009-05-08 10:31:42 +0800136/*
137 * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events.
138 */
139static int __ftrace_set_clr_event(const char *match, const char *sub,
140 const char *event, int set)
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500141{
Steven Rostedta59fd602009-04-10 13:52:20 -0400142 struct ftrace_event_call *call;
Steven Rostedt29f93942009-05-08 16:06:47 -0400143 int ret = -EINVAL;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500144
Steven Rostedt11a241a2009-03-02 11:49:04 -0500145 mutex_lock(&event_mutex);
Steven Rostedta59fd602009-04-10 13:52:20 -0400146 list_for_each_entry(call, &ftrace_events, list) {
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500147
Steven Rostedt40e26812009-03-10 11:32:40 -0400148 if (!call->name || !call->regfunc)
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500149 continue;
Steven Rostedt1473e442009-02-24 14:15:08 -0500150
Steven Rostedtb628b3e2009-02-27 23:32:58 -0500151 if (match &&
152 strcmp(match, call->name) != 0 &&
153 strcmp(match, call->system) != 0)
154 continue;
155
156 if (sub && strcmp(sub, call->system) != 0)
157 continue;
158
159 if (event && strcmp(event, call->name) != 0)
Steven Rostedt1473e442009-02-24 14:15:08 -0500160 continue;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500161
Steven Rostedtfd994982009-02-28 02:41:25 -0500162 ftrace_event_enable_disable(call, set);
163
Steven Rostedtb628b3e2009-02-27 23:32:58 -0500164 ret = 0;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500165 }
Steven Rostedt11a241a2009-03-02 11:49:04 -0500166 mutex_unlock(&event_mutex);
167
Steven Rostedtb628b3e2009-02-27 23:32:58 -0500168 return ret;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500169}
170
Li Zefan8f31bfe2009-05-08 10:31:42 +0800171static int ftrace_set_clr_event(char *buf, int set)
172{
173 char *event = NULL, *sub = NULL, *match;
174
175 /*
176 * The buf format can be <subsystem>:<event-name>
177 * *:<event-name> means any event by that name.
178 * :<event-name> is the same.
179 *
180 * <subsystem>:* means all events in that subsystem
181 * <subsystem>: means the same.
182 *
183 * <name> (no ':') means all events in a subsystem with
184 * the name <name> or any event that matches <name>
185 */
186
187 match = strsep(&buf, ":");
188 if (buf) {
189 sub = match;
190 event = buf;
191 match = NULL;
192
193 if (!strlen(sub) || strcmp(sub, "*") == 0)
194 sub = NULL;
195 if (!strlen(event) || strcmp(event, "*") == 0)
196 event = NULL;
197 }
198
199 return __ftrace_set_clr_event(match, sub, event, set);
200}
201
Steven Rostedt4671c792009-05-08 16:27:41 -0400202/**
203 * trace_set_clr_event - enable or disable an event
204 * @system: system name to match (NULL for any system)
205 * @event: event name to match (NULL for all events, within system)
206 * @set: 1 to enable, 0 to disable
207 *
208 * This is a way for other parts of the kernel to enable or disable
209 * event recording.
210 *
211 * Returns 0 on success, -EINVAL if the parameters do not match any
212 * registered events.
213 */
214int trace_set_clr_event(const char *system, const char *event, int set)
215{
216 return __ftrace_set_clr_event(NULL, system, event, set);
217}
218
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500219/* 128 should be much more than enough */
220#define EVENT_BUF_SIZE 127
221
222static ssize_t
223ftrace_event_write(struct file *file, const char __user *ubuf,
224 size_t cnt, loff_t *ppos)
225{
226 size_t read = 0;
227 int i, set = 1;
228 ssize_t ret;
229 char *buf;
230 char ch;
231
232 if (!cnt || cnt < 0)
233 return 0;
234
Steven Rostedt1852fcc2009-03-11 14:33:00 -0400235 ret = tracing_update_buffers();
236 if (ret < 0)
237 return ret;
238
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500239 ret = get_user(ch, ubuf++);
240 if (ret)
241 return ret;
242 read++;
243 cnt--;
244
245 /* skip white space */
246 while (cnt && isspace(ch)) {
247 ret = get_user(ch, ubuf++);
248 if (ret)
249 return ret;
250 read++;
251 cnt--;
252 }
253
254 /* Only white space found? */
255 if (isspace(ch)) {
256 file->f_pos += read;
257 ret = read;
258 return ret;
259 }
260
261 buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
262 if (!buf)
263 return -ENOMEM;
264
265 if (cnt > EVENT_BUF_SIZE)
266 cnt = EVENT_BUF_SIZE;
267
268 i = 0;
269 while (cnt && !isspace(ch)) {
270 if (!i && ch == '!')
271 set = 0;
272 else
273 buf[i++] = ch;
274
275 ret = get_user(ch, ubuf++);
276 if (ret)
277 goto out_free;
278 read++;
279 cnt--;
280 }
281 buf[i] = 0;
282
283 file->f_pos += read;
284
285 ret = ftrace_set_clr_event(buf, set);
286 if (ret)
287 goto out_free;
288
289 ret = read;
290
291 out_free:
292 kfree(buf);
293
294 return ret;
295}
296
297static void *
298t_next(struct seq_file *m, void *v, loff_t *pos)
299{
Steven Rostedta59fd602009-04-10 13:52:20 -0400300 struct list_head *list = m->private;
301 struct ftrace_event_call *call;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500302
303 (*pos)++;
304
Steven Rostedt40e26812009-03-10 11:32:40 -0400305 for (;;) {
Steven Rostedta59fd602009-04-10 13:52:20 -0400306 if (list == &ftrace_events)
Steven Rostedt40e26812009-03-10 11:32:40 -0400307 return NULL;
308
Steven Rostedta59fd602009-04-10 13:52:20 -0400309 call = list_entry(list, struct ftrace_event_call, list);
310
Steven Rostedt40e26812009-03-10 11:32:40 -0400311 /*
312 * The ftrace subsystem is for showing formats only.
313 * They can not be enabled or disabled via the event files.
314 */
315 if (call->regfunc)
316 break;
317
Steven Rostedta59fd602009-04-10 13:52:20 -0400318 list = list->next;
Steven Rostedt40e26812009-03-10 11:32:40 -0400319 }
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500320
Steven Rostedta59fd602009-04-10 13:52:20 -0400321 m->private = list->next;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500322
323 return call;
324}
325
326static void *t_start(struct seq_file *m, loff_t *pos)
327{
Li Zefane1c7e2a2009-06-24 09:52:29 +0800328 struct ftrace_event_call *call = NULL;
329 loff_t l;
330
Li Zefan20c89282009-05-06 10:33:45 +0800331 mutex_lock(&event_mutex);
Li Zefane1c7e2a2009-06-24 09:52:29 +0800332
333 m->private = ftrace_events.next;
334 for (l = 0; l <= *pos; ) {
335 call = t_next(m, NULL, &l);
336 if (!call)
337 break;
338 }
339 return call;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500340}
341
342static void *
343s_next(struct seq_file *m, void *v, loff_t *pos)
344{
Steven Rostedta59fd602009-04-10 13:52:20 -0400345 struct list_head *list = m->private;
346 struct ftrace_event_call *call;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500347
348 (*pos)++;
349
350 retry:
Steven Rostedta59fd602009-04-10 13:52:20 -0400351 if (list == &ftrace_events)
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500352 return NULL;
353
Steven Rostedta59fd602009-04-10 13:52:20 -0400354 call = list_entry(list, struct ftrace_event_call, list);
355
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500356 if (!call->enabled) {
Steven Rostedta59fd602009-04-10 13:52:20 -0400357 list = list->next;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500358 goto retry;
359 }
360
Steven Rostedta59fd602009-04-10 13:52:20 -0400361 m->private = list->next;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500362
363 return call;
364}
365
366static void *s_start(struct seq_file *m, loff_t *pos)
367{
Li Zefane1c7e2a2009-06-24 09:52:29 +0800368 struct ftrace_event_call *call = NULL;
369 loff_t l;
370
Li Zefan20c89282009-05-06 10:33:45 +0800371 mutex_lock(&event_mutex);
Li Zefane1c7e2a2009-06-24 09:52:29 +0800372
373 m->private = ftrace_events.next;
374 for (l = 0; l <= *pos; ) {
375 call = s_next(m, NULL, &l);
376 if (!call)
377 break;
378 }
379 return call;
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500380}
381
382static int t_show(struct seq_file *m, void *v)
383{
384 struct ftrace_event_call *call = v;
385
Steven Rostedtb628b3e2009-02-27 23:32:58 -0500386 if (strcmp(call->system, TRACE_SYSTEM) != 0)
387 seq_printf(m, "%s:", call->system);
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500388 seq_printf(m, "%s\n", call->name);
389
390 return 0;
391}
392
393static void t_stop(struct seq_file *m, void *p)
394{
Li Zefan20c89282009-05-06 10:33:45 +0800395 mutex_unlock(&event_mutex);
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500396}
397
398static int
399ftrace_event_seq_open(struct inode *inode, struct file *file)
400{
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500401 const struct seq_operations *seq_ops;
402
403 if ((file->f_mode & FMODE_WRITE) &&
Steven Rostedt8650ae32009-07-22 23:29:30 -0400404 (file->f_flags & O_TRUNC))
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500405 ftrace_clear_events();
406
407 seq_ops = inode->i_private;
Li Zefan20c89282009-05-06 10:33:45 +0800408 return seq_open(file, seq_ops);
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500409}
410
Steven Rostedt1473e442009-02-24 14:15:08 -0500411static ssize_t
412event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
413 loff_t *ppos)
414{
415 struct ftrace_event_call *call = filp->private_data;
416 char *buf;
417
Steven Rostedtda4d0302009-03-09 17:14:30 -0400418 if (call->enabled)
Steven Rostedt1473e442009-02-24 14:15:08 -0500419 buf = "1\n";
420 else
421 buf = "0\n";
422
423 return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
424}
425
426static ssize_t
427event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
428 loff_t *ppos)
429{
430 struct ftrace_event_call *call = filp->private_data;
431 char buf[64];
432 unsigned long val;
433 int ret;
434
435 if (cnt >= sizeof(buf))
436 return -EINVAL;
437
438 if (copy_from_user(&buf, ubuf, cnt))
439 return -EFAULT;
440
441 buf[cnt] = 0;
442
443 ret = strict_strtoul(buf, 10, &val);
444 if (ret < 0)
445 return ret;
446
Steven Rostedt1852fcc2009-03-11 14:33:00 -0400447 ret = tracing_update_buffers();
448 if (ret < 0)
449 return ret;
450
Steven Rostedt1473e442009-02-24 14:15:08 -0500451 switch (val) {
452 case 0:
Steven Rostedt1473e442009-02-24 14:15:08 -0500453 case 1:
Steven Rostedt11a241a2009-03-02 11:49:04 -0500454 mutex_lock(&event_mutex);
Steven Rostedtfd994982009-02-28 02:41:25 -0500455 ftrace_event_enable_disable(call, val);
Steven Rostedt11a241a2009-03-02 11:49:04 -0500456 mutex_unlock(&event_mutex);
Steven Rostedt1473e442009-02-24 14:15:08 -0500457 break;
458
459 default:
460 return -EINVAL;
461 }
462
463 *ppos += cnt;
464
465 return cnt;
466}
467
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400468static ssize_t
469system_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
470 loff_t *ppos)
471{
Li Zefanc142b152009-05-08 10:32:05 +0800472 const char set_to_char[4] = { '?', '0', '1', 'X' };
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400473 const char *system = filp->private_data;
474 struct ftrace_event_call *call;
475 char buf[2];
Li Zefanc142b152009-05-08 10:32:05 +0800476 int set = 0;
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400477 int ret;
478
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400479 mutex_lock(&event_mutex);
480 list_for_each_entry(call, &ftrace_events, list) {
481 if (!call->name || !call->regfunc)
482 continue;
483
Li Zefan8f31bfe2009-05-08 10:31:42 +0800484 if (system && strcmp(call->system, system) != 0)
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400485 continue;
486
487 /*
488 * We need to find out if all the events are set
489 * or if all events or cleared, or if we have
490 * a mixture.
491 */
Li Zefanc142b152009-05-08 10:32:05 +0800492 set |= (1 << !!call->enabled);
493
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400494 /*
495 * If we have a mixture, no need to look further.
496 */
Li Zefanc142b152009-05-08 10:32:05 +0800497 if (set == 3)
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400498 break;
499 }
500 mutex_unlock(&event_mutex);
501
Li Zefanc142b152009-05-08 10:32:05 +0800502 buf[0] = set_to_char[set];
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400503 buf[1] = '\n';
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400504
505 ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
506
507 return ret;
508}
509
510static ssize_t
511system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
512 loff_t *ppos)
513{
514 const char *system = filp->private_data;
515 unsigned long val;
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400516 char buf[64];
517 ssize_t ret;
518
519 if (cnt >= sizeof(buf))
520 return -EINVAL;
521
522 if (copy_from_user(&buf, ubuf, cnt))
523 return -EFAULT;
524
525 buf[cnt] = 0;
526
527 ret = strict_strtoul(buf, 10, &val);
528 if (ret < 0)
529 return ret;
530
531 ret = tracing_update_buffers();
532 if (ret < 0)
533 return ret;
534
Li Zefan8f31bfe2009-05-08 10:31:42 +0800535 if (val != 0 && val != 1)
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400536 return -EINVAL;
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400537
Li Zefan8f31bfe2009-05-08 10:31:42 +0800538 ret = __ftrace_set_clr_event(NULL, system, NULL, val);
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400539 if (ret)
Li Zefan8f31bfe2009-05-08 10:31:42 +0800540 goto out;
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400541
542 ret = cnt;
543
Li Zefan8f31bfe2009-05-08 10:31:42 +0800544out:
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400545 *ppos += cnt;
546
547 return ret;
548}
549
Steven Rostedt75db37d2009-03-26 11:43:36 -0400550extern char *__bad_type_size(void);
551
Steven Rostedt91729ef2009-03-02 15:03:01 -0500552#undef FIELD
Steven Rostedt156b5f12009-03-06 10:50:53 -0500553#define FIELD(type, name) \
Steven Rostedt75db37d2009-03-26 11:43:36 -0400554 sizeof(type) != sizeof(field.name) ? __bad_type_size() : \
Tom Zanussicf027f62009-03-22 03:30:39 -0500555 #type, "common_" #name, offsetof(typeof(field), name), \
556 sizeof(field.name)
Steven Rostedt91729ef2009-03-02 15:03:01 -0500557
558static int trace_write_header(struct trace_seq *s)
559{
560 struct trace_entry field;
561
562 /* struct trace_entry */
563 return trace_seq_printf(s,
Steven Rostedtce8eb2b2009-03-10 10:14:35 -0400564 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
565 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
566 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
567 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
568 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
Steven Rostedt91729ef2009-03-02 15:03:01 -0500569 "\n",
Steven Rostedt89ec0de2009-03-26 11:03:29 -0400570 FIELD(unsigned short, type),
Steven Rostedt91729ef2009-03-02 15:03:01 -0500571 FIELD(unsigned char, flags),
572 FIELD(unsigned char, preempt_count),
573 FIELD(int, pid),
574 FIELD(int, tgid));
575}
Steven Rostedtda4d0302009-03-09 17:14:30 -0400576
Steven Rostedt981d0812009-03-02 13:53:59 -0500577static ssize_t
578event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
579 loff_t *ppos)
580{
581 struct ftrace_event_call *call = filp->private_data;
582 struct trace_seq *s;
583 char *buf;
584 int r;
585
Tom Zanussic269fc82009-03-17 01:20:59 -0500586 if (*ppos)
587 return 0;
588
Steven Rostedt981d0812009-03-02 13:53:59 -0500589 s = kmalloc(sizeof(*s), GFP_KERNEL);
590 if (!s)
591 return -ENOMEM;
592
593 trace_seq_init(s);
594
Steven Rostedtc5e4e192009-03-02 15:10:02 -0500595 /* If any of the first writes fail, so will the show_format. */
596
597 trace_seq_printf(s, "name: %s\n", call->name);
598 trace_seq_printf(s, "ID: %d\n", call->id);
599 trace_seq_printf(s, "format:\n");
Steven Rostedt91729ef2009-03-02 15:03:01 -0500600 trace_write_header(s);
601
Frederic Weisbeckere8f9f4d2009-08-11 17:42:52 +0200602 r = call->show_format(call, s);
Steven Rostedt981d0812009-03-02 13:53:59 -0500603 if (!r) {
604 /*
605 * ug! The format output is bigger than a PAGE!!
606 */
607 buf = "FORMAT TOO BIG\n";
608 r = simple_read_from_buffer(ubuf, cnt, ppos,
609 buf, strlen(buf));
610 goto out;
611 }
612
613 r = simple_read_from_buffer(ubuf, cnt, ppos,
614 s->buffer, s->len);
615 out:
616 kfree(s);
617 return r;
618}
619
Peter Zijlstra23725ae2009-03-19 20:26:13 +0100620static ssize_t
621event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
622{
623 struct ftrace_event_call *call = filp->private_data;
624 struct trace_seq *s;
625 int r;
626
627 if (*ppos)
628 return 0;
629
630 s = kmalloc(sizeof(*s), GFP_KERNEL);
631 if (!s)
632 return -ENOMEM;
633
634 trace_seq_init(s);
635 trace_seq_printf(s, "%d\n", call->id);
636
637 r = simple_read_from_buffer(ubuf, cnt, ppos,
638 s->buffer, s->len);
639 kfree(s);
640 return r;
641}
642
Tom Zanussi7ce7e422009-03-22 03:31:04 -0500643static ssize_t
644event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
645 loff_t *ppos)
646{
647 struct ftrace_event_call *call = filp->private_data;
648 struct trace_seq *s;
649 int r;
650
651 if (*ppos)
652 return 0;
653
654 s = kmalloc(sizeof(*s), GFP_KERNEL);
655 if (!s)
656 return -ENOMEM;
657
658 trace_seq_init(s);
659
Tom Zanussi8b372562009-04-28 03:04:59 -0500660 print_event_filter(call, s);
Tom Zanussi4bda2d52009-03-24 02:14:31 -0500661 r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
Tom Zanussi7ce7e422009-03-22 03:31:04 -0500662
663 kfree(s);
664
665 return r;
666}
667
668static ssize_t
669event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
670 loff_t *ppos)
671{
672 struct ftrace_event_call *call = filp->private_data;
Tom Zanussi8b372562009-04-28 03:04:59 -0500673 char *buf;
Tom Zanussi7ce7e422009-03-22 03:31:04 -0500674 int err;
675
Tom Zanussi8b372562009-04-28 03:04:59 -0500676 if (cnt >= PAGE_SIZE)
Tom Zanussi7ce7e422009-03-22 03:31:04 -0500677 return -EINVAL;
678
Tom Zanussi8b372562009-04-28 03:04:59 -0500679 buf = (char *)__get_free_page(GFP_TEMPORARY);
680 if (!buf)
Tom Zanussi7ce7e422009-03-22 03:31:04 -0500681 return -ENOMEM;
682
Tom Zanussi8b372562009-04-28 03:04:59 -0500683 if (copy_from_user(buf, ubuf, cnt)) {
684 free_page((unsigned long) buf);
685 return -EFAULT;
686 }
687 buf[cnt] = '\0';
688
689 err = apply_event_filter(call, buf);
690 free_page((unsigned long) buf);
691 if (err < 0)
Tom Zanussi7ce7e422009-03-22 03:31:04 -0500692 return err;
Tom Zanussi0a19e532009-04-13 03:17:50 -0500693
Tom Zanussi7ce7e422009-03-22 03:31:04 -0500694 *ppos += cnt;
695
696 return cnt;
697}
698
Tom Zanussicfb180f2009-03-22 03:31:17 -0500699static ssize_t
700subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
701 loff_t *ppos)
702{
703 struct event_subsystem *system = filp->private_data;
704 struct trace_seq *s;
705 int r;
706
707 if (*ppos)
708 return 0;
709
710 s = kmalloc(sizeof(*s), GFP_KERNEL);
711 if (!s)
712 return -ENOMEM;
713
714 trace_seq_init(s);
715
Tom Zanussi8b372562009-04-28 03:04:59 -0500716 print_subsystem_event_filter(system, s);
Tom Zanussi4bda2d52009-03-24 02:14:31 -0500717 r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
Tom Zanussicfb180f2009-03-22 03:31:17 -0500718
719 kfree(s);
720
721 return r;
722}
723
724static ssize_t
725subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
726 loff_t *ppos)
727{
728 struct event_subsystem *system = filp->private_data;
Tom Zanussi8b372562009-04-28 03:04:59 -0500729 char *buf;
Tom Zanussicfb180f2009-03-22 03:31:17 -0500730 int err;
731
Tom Zanussi8b372562009-04-28 03:04:59 -0500732 if (cnt >= PAGE_SIZE)
Tom Zanussicfb180f2009-03-22 03:31:17 -0500733 return -EINVAL;
734
Tom Zanussi8b372562009-04-28 03:04:59 -0500735 buf = (char *)__get_free_page(GFP_TEMPORARY);
736 if (!buf)
Tom Zanussicfb180f2009-03-22 03:31:17 -0500737 return -ENOMEM;
738
Tom Zanussi8b372562009-04-28 03:04:59 -0500739 if (copy_from_user(buf, ubuf, cnt)) {
740 free_page((unsigned long) buf);
741 return -EFAULT;
Tom Zanussicfb180f2009-03-22 03:31:17 -0500742 }
Tom Zanussi8b372562009-04-28 03:04:59 -0500743 buf[cnt] = '\0';
Tom Zanussicfb180f2009-03-22 03:31:17 -0500744
Tom Zanussi8b372562009-04-28 03:04:59 -0500745 err = apply_subsystem_event_filter(system, buf);
746 free_page((unsigned long) buf);
747 if (err < 0)
Li Zefan44e9c8b2009-04-11 15:55:28 +0800748 return err;
Tom Zanussicfb180f2009-03-22 03:31:17 -0500749
750 *ppos += cnt;
751
752 return cnt;
753}
754
Steven Rostedtd1b182a2009-04-15 16:53:47 -0400755static ssize_t
756show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
757{
758 int (*func)(struct trace_seq *s) = filp->private_data;
759 struct trace_seq *s;
760 int r;
761
762 if (*ppos)
763 return 0;
764
765 s = kmalloc(sizeof(*s), GFP_KERNEL);
766 if (!s)
767 return -ENOMEM;
768
769 trace_seq_init(s);
770
771 func(s);
772 r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
773
774 kfree(s);
775
776 return r;
777}
778
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500779static const struct seq_operations show_event_seq_ops = {
780 .start = t_start,
781 .next = t_next,
782 .show = t_show,
783 .stop = t_stop,
784};
785
786static const struct seq_operations show_set_event_seq_ops = {
787 .start = s_start,
788 .next = s_next,
789 .show = t_show,
790 .stop = t_stop,
791};
792
Steven Rostedt2314c4a2009-03-10 12:04:02 -0400793static const struct file_operations ftrace_avail_fops = {
794 .open = ftrace_event_seq_open,
795 .read = seq_read,
796 .llseek = seq_lseek,
797 .release = seq_release,
798};
799
Steven Rostedtb77e38a2009-02-24 10:21:36 -0500800static const struct file_operations ftrace_set_event_fops = {
801 .open = ftrace_event_seq_open,
802 .read = seq_read,
803 .write = ftrace_event_write,
804 .llseek = seq_lseek,
805 .release = seq_release,
806};
807
Steven Rostedt1473e442009-02-24 14:15:08 -0500808static const struct file_operations ftrace_enable_fops = {
809 .open = tracing_open_generic,
810 .read = event_enable_read,
811 .write = event_enable_write,
812};
813
Steven Rostedt981d0812009-03-02 13:53:59 -0500814static const struct file_operations ftrace_event_format_fops = {
815 .open = tracing_open_generic,
816 .read = event_format_read,
817};
818
Peter Zijlstra23725ae2009-03-19 20:26:13 +0100819static const struct file_operations ftrace_event_id_fops = {
820 .open = tracing_open_generic,
821 .read = event_id_read,
822};
823
Tom Zanussi7ce7e422009-03-22 03:31:04 -0500824static const struct file_operations ftrace_event_filter_fops = {
825 .open = tracing_open_generic,
826 .read = event_filter_read,
827 .write = event_filter_write,
828};
829
Tom Zanussicfb180f2009-03-22 03:31:17 -0500830static const struct file_operations ftrace_subsystem_filter_fops = {
831 .open = tracing_open_generic,
832 .read = subsystem_filter_read,
833 .write = subsystem_filter_write,
834};
835
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400836static const struct file_operations ftrace_system_enable_fops = {
837 .open = tracing_open_generic,
838 .read = system_enable_read,
839 .write = system_enable_write,
840};
841
Steven Rostedtd1b182a2009-04-15 16:53:47 -0400842static const struct file_operations ftrace_show_header_fops = {
843 .open = tracing_open_generic,
844 .read = show_header,
845};
846
Steven Rostedt1473e442009-02-24 14:15:08 -0500847static struct dentry *event_trace_events_dir(void)
848{
849 static struct dentry *d_tracer;
850 static struct dentry *d_events;
851
852 if (d_events)
853 return d_events;
854
855 d_tracer = tracing_init_dentry();
856 if (!d_tracer)
857 return NULL;
858
859 d_events = debugfs_create_dir("events", d_tracer);
860 if (!d_events)
861 pr_warning("Could not create debugfs "
862 "'events' directory\n");
863
864 return d_events;
865}
866
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500867static LIST_HEAD(event_subsystems);
868
869static struct dentry *
870event_subsystem_dir(const char *name, struct dentry *d_events)
871{
872 struct event_subsystem *system;
Tom Zanussie1112b42009-03-31 00:48:49 -0500873 struct dentry *entry;
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500874
875 /* First see if we did not already create this dir */
876 list_for_each_entry(system, &event_subsystems, list) {
Xiao Guangrongdc82ec98a2009-07-09 16:22:22 +0800877 if (strcmp(system->name, name) == 0) {
878 system->nr_events++;
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500879 return system->entry;
Xiao Guangrongdc82ec98a2009-07-09 16:22:22 +0800880 }
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500881 }
882
883 /* need to create new entry */
884 system = kmalloc(sizeof(*system), GFP_KERNEL);
885 if (!system) {
886 pr_warning("No memory to create event subsystem %s\n",
887 name);
888 return d_events;
889 }
890
891 system->entry = debugfs_create_dir(name, d_events);
892 if (!system->entry) {
893 pr_warning("Could not create event subsystem %s\n",
894 name);
895 kfree(system);
896 return d_events;
897 }
898
Xiao Guangrongdc82ec98a2009-07-09 16:22:22 +0800899 system->nr_events = 1;
Steven Rostedt6d723732009-04-10 14:53:50 -0400900 system->name = kstrdup(name, GFP_KERNEL);
901 if (!system->name) {
902 debugfs_remove(system->entry);
903 kfree(system);
904 return d_events;
905 }
906
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500907 list_add(&system->list, &event_subsystems);
908
Tom Zanussi30e673b2009-04-28 03:04:47 -0500909 system->filter = NULL;
Tom Zanussicfb180f2009-03-22 03:31:17 -0500910
Tom Zanussi8b372562009-04-28 03:04:59 -0500911 system->filter = kzalloc(sizeof(struct event_filter), GFP_KERNEL);
912 if (!system->filter) {
913 pr_warning("Could not allocate filter for subsystem "
914 "'%s'\n", name);
915 return system->entry;
916 }
917
Tom Zanussie1112b42009-03-31 00:48:49 -0500918 entry = debugfs_create_file("filter", 0644, system->entry, system,
919 &ftrace_subsystem_filter_fops);
Tom Zanussi8b372562009-04-28 03:04:59 -0500920 if (!entry) {
921 kfree(system->filter);
922 system->filter = NULL;
Tom Zanussie1112b42009-03-31 00:48:49 -0500923 pr_warning("Could not create debugfs "
924 "'%s/filter' entry\n", name);
Tom Zanussi8b372562009-04-28 03:04:59 -0500925 }
Tom Zanussie1112b42009-03-31 00:48:49 -0500926
Steven Rostedt8ae79a12009-05-06 22:52:15 -0400927 entry = trace_create_file("enable", 0644, system->entry,
928 (void *)system->name,
929 &ftrace_system_enable_fops);
930
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500931 return system->entry;
932}
933
Steven Rostedt1473e442009-02-24 14:15:08 -0500934static int
Steven Rostedt701970b2009-04-24 23:11:22 -0400935event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
936 const struct file_operations *id,
937 const struct file_operations *enable,
938 const struct file_operations *filter,
939 const struct file_operations *format)
Steven Rostedt1473e442009-02-24 14:15:08 -0500940{
941 struct dentry *entry;
Steven Rostedtfd994982009-02-28 02:41:25 -0500942 int ret;
Steven Rostedt1473e442009-02-24 14:15:08 -0500943
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500944 /*
945 * If the trace point header did not define TRACE_SYSTEM
946 * then the system would be called "TRACE_SYSTEM".
947 */
Steven Rostedt6d723732009-04-10 14:53:50 -0400948 if (strcmp(call->system, TRACE_SYSTEM) != 0)
Steven Rostedt6ecc2d12009-02-27 21:33:02 -0500949 d_events = event_subsystem_dir(call->system, d_events);
950
Steven Rostedt1473e442009-02-24 14:15:08 -0500951 call->dir = debugfs_create_dir(call->name, d_events);
952 if (!call->dir) {
953 pr_warning("Could not create debugfs "
954 "'%s' directory\n", call->name);
955 return -1;
956 }
957
Steven Rostedt6d723732009-04-10 14:53:50 -0400958 if (call->regfunc)
959 entry = trace_create_file("enable", 0644, call->dir, call,
Steven Rostedt701970b2009-04-24 23:11:22 -0400960 enable);
Steven Rostedt1473e442009-02-24 14:15:08 -0500961
Peter Zijlstraaf6af302009-08-05 20:41:04 +0200962 if (call->id && call->profile_enable)
Steven Rostedt6d723732009-04-10 14:53:50 -0400963 entry = trace_create_file("id", 0444, call->dir, call,
Steven Rostedt701970b2009-04-24 23:11:22 -0400964 id);
Peter Zijlstra23725ae2009-03-19 20:26:13 +0100965
Tom Zanussicf027f62009-03-22 03:30:39 -0500966 if (call->define_fields) {
Li Zefan14be96c2009-08-19 15:53:52 +0800967 ret = call->define_fields(call);
Tom Zanussicf027f62009-03-22 03:30:39 -0500968 if (ret < 0) {
969 pr_warning("Could not initialize trace point"
970 " events/%s\n", call->name);
971 return ret;
972 }
Steven Rostedt6d723732009-04-10 14:53:50 -0400973 entry = trace_create_file("filter", 0644, call->dir, call,
Steven Rostedt701970b2009-04-24 23:11:22 -0400974 filter);
Tom Zanussicf027f62009-03-22 03:30:39 -0500975 }
976
Steven Rostedt981d0812009-03-02 13:53:59 -0500977 /* A trace may not want to export its format */
978 if (!call->show_format)
979 return 0;
980
Steven Rostedt6d723732009-04-10 14:53:50 -0400981 entry = trace_create_file("format", 0444, call->dir, call,
Steven Rostedt701970b2009-04-24 23:11:22 -0400982 format);
Steven Rostedtfd994982009-02-28 02:41:25 -0500983
Steven Rostedt1473e442009-02-24 14:15:08 -0500984 return 0;
985}
986
Steven Rostedt6d723732009-04-10 14:53:50 -0400987#define for_each_event(event, start, end) \
988 for (event = start; \
989 (unsigned long)event < (unsigned long)end; \
990 event++)
991
Steven Rostedt61f919a2009-04-14 18:22:32 -0400992#ifdef CONFIG_MODULES
Steven Rostedt701970b2009-04-24 23:11:22 -0400993
994static LIST_HEAD(ftrace_module_file_list);
995
996/*
997 * Modules must own their file_operations to keep up with
998 * reference counting.
999 */
1000struct ftrace_module_file_ops {
1001 struct list_head list;
1002 struct module *mod;
1003 struct file_operations id;
1004 struct file_operations enable;
1005 struct file_operations format;
1006 struct file_operations filter;
1007};
1008
Frederic Weisbeckera2ca5e02009-08-06 07:32:21 +02001009static void remove_subsystem_dir(const char *name)
1010{
1011 struct event_subsystem *system;
1012
1013 if (strcmp(name, TRACE_SYSTEM) == 0)
1014 return;
1015
1016 list_for_each_entry(system, &event_subsystems, list) {
1017 if (strcmp(system->name, name) == 0) {
1018 if (!--system->nr_events) {
1019 struct event_filter *filter = system->filter;
1020
1021 debugfs_remove_recursive(system->entry);
1022 list_del(&system->list);
1023 if (filter) {
1024 kfree(filter->filter_string);
1025 kfree(filter);
1026 }
1027 kfree(system->name);
1028 kfree(system);
1029 }
1030 break;
1031 }
1032 }
1033}
1034
Steven Rostedt701970b2009-04-24 23:11:22 -04001035static struct ftrace_module_file_ops *
1036trace_create_file_ops(struct module *mod)
1037{
1038 struct ftrace_module_file_ops *file_ops;
1039
1040 /*
1041 * This is a bit of a PITA. To allow for correct reference
1042 * counting, modules must "own" their file_operations.
1043 * To do this, we allocate the file operations that will be
1044 * used in the event directory.
1045 */
1046
1047 file_ops = kmalloc(sizeof(*file_ops), GFP_KERNEL);
1048 if (!file_ops)
1049 return NULL;
1050
1051 file_ops->mod = mod;
1052
1053 file_ops->id = ftrace_event_id_fops;
1054 file_ops->id.owner = mod;
1055
1056 file_ops->enable = ftrace_enable_fops;
1057 file_ops->enable.owner = mod;
1058
1059 file_ops->filter = ftrace_event_filter_fops;
1060 file_ops->filter.owner = mod;
1061
1062 file_ops->format = ftrace_event_format_fops;
1063 file_ops->format.owner = mod;
1064
1065 list_add(&file_ops->list, &ftrace_module_file_list);
1066
1067 return file_ops;
1068}
1069
Steven Rostedt6d723732009-04-10 14:53:50 -04001070static void trace_module_add_events(struct module *mod)
1071{
Steven Rostedt701970b2009-04-24 23:11:22 -04001072 struct ftrace_module_file_ops *file_ops = NULL;
Steven Rostedt6d723732009-04-10 14:53:50 -04001073 struct ftrace_event_call *call, *start, *end;
1074 struct dentry *d_events;
Jason Baronf744bd52009-08-10 16:52:39 -04001075 int ret;
Steven Rostedt6d723732009-04-10 14:53:50 -04001076
1077 start = mod->trace_events;
1078 end = mod->trace_events + mod->num_trace_events;
1079
1080 if (start == end)
1081 return;
1082
1083 d_events = event_trace_events_dir();
1084 if (!d_events)
1085 return;
1086
1087 for_each_event(call, start, end) {
1088 /* The linker may leave blanks */
1089 if (!call->name)
1090 continue;
Jason Baronf744bd52009-08-10 16:52:39 -04001091 if (call->raw_init) {
1092 ret = call->raw_init();
1093 if (ret < 0) {
1094 if (ret != -ENOSYS)
1095 pr_warning("Could not initialize trace "
1096 "point events/%s\n", call->name);
1097 continue;
1098 }
1099 }
Steven Rostedt701970b2009-04-24 23:11:22 -04001100 /*
1101 * This module has events, create file ops for this module
1102 * if not already done.
1103 */
1104 if (!file_ops) {
1105 file_ops = trace_create_file_ops(mod);
1106 if (!file_ops)
1107 return;
1108 }
Steven Rostedt6d723732009-04-10 14:53:50 -04001109 call->mod = mod;
1110 list_add(&call->list, &ftrace_events);
Steven Rostedt701970b2009-04-24 23:11:22 -04001111 event_create_dir(call, d_events,
1112 &file_ops->id, &file_ops->enable,
1113 &file_ops->filter, &file_ops->format);
Steven Rostedt6d723732009-04-10 14:53:50 -04001114 }
1115}
1116
1117static void trace_module_remove_events(struct module *mod)
1118{
Steven Rostedt701970b2009-04-24 23:11:22 -04001119 struct ftrace_module_file_ops *file_ops;
Steven Rostedt6d723732009-04-10 14:53:50 -04001120 struct ftrace_event_call *call, *p;
Steven Rostedt9456f0f2009-05-06 21:54:09 -04001121 bool found = false;
Steven Rostedt6d723732009-04-10 14:53:50 -04001122
Steven Rostedt110bf2b2009-06-09 17:29:07 -04001123 down_write(&trace_event_mutex);
Steven Rostedt6d723732009-04-10 14:53:50 -04001124 list_for_each_entry_safe(call, p, &ftrace_events, list) {
1125 if (call->mod == mod) {
Steven Rostedt9456f0f2009-05-06 21:54:09 -04001126 found = true;
Zhaolei0e907c92009-05-25 18:13:59 +08001127 ftrace_event_enable_disable(call, 0);
Steven Rostedt6d723732009-04-10 14:53:50 -04001128 if (call->event)
Steven Rostedt110bf2b2009-06-09 17:29:07 -04001129 __unregister_ftrace_event(call->event);
Steven Rostedt6d723732009-04-10 14:53:50 -04001130 debugfs_remove_recursive(call->dir);
1131 list_del(&call->list);
Li Zefan2df75e42009-05-06 10:33:04 +08001132 trace_destroy_fields(call);
1133 destroy_preds(call);
Xiao Guangrongdc82ec98a2009-07-09 16:22:22 +08001134 remove_subsystem_dir(call->system);
Steven Rostedt6d723732009-04-10 14:53:50 -04001135 }
1136 }
Steven Rostedt701970b2009-04-24 23:11:22 -04001137
1138 /* Now free the file_operations */
1139 list_for_each_entry(file_ops, &ftrace_module_file_list, list) {
1140 if (file_ops->mod == mod)
1141 break;
1142 }
1143 if (&file_ops->list != &ftrace_module_file_list) {
1144 list_del(&file_ops->list);
1145 kfree(file_ops);
1146 }
Steven Rostedt9456f0f2009-05-06 21:54:09 -04001147
1148 /*
1149 * It is safest to reset the ring buffer if the module being unloaded
1150 * registered any events.
1151 */
1152 if (found)
1153 tracing_reset_current_online_cpus();
Steven Rostedt110bf2b2009-06-09 17:29:07 -04001154 up_write(&trace_event_mutex);
Steven Rostedt6d723732009-04-10 14:53:50 -04001155}
1156
Steven Rostedt61f919a2009-04-14 18:22:32 -04001157static int trace_module_notify(struct notifier_block *self,
1158 unsigned long val, void *data)
Steven Rostedt6d723732009-04-10 14:53:50 -04001159{
1160 struct module *mod = data;
1161
1162 mutex_lock(&event_mutex);
1163 switch (val) {
1164 case MODULE_STATE_COMING:
1165 trace_module_add_events(mod);
1166 break;
1167 case MODULE_STATE_GOING:
1168 trace_module_remove_events(mod);
1169 break;
1170 }
1171 mutex_unlock(&event_mutex);
1172
1173 return 0;
1174}
Steven Rostedt61f919a2009-04-14 18:22:32 -04001175#else
1176static int trace_module_notify(struct notifier_block *self,
1177 unsigned long val, void *data)
1178{
1179 return 0;
1180}
1181#endif /* CONFIG_MODULES */
Steven Rostedt6d723732009-04-10 14:53:50 -04001182
1183struct notifier_block trace_module_nb = {
1184 .notifier_call = trace_module_notify,
1185 .priority = 0,
1186};
1187
Steven Rostedta59fd602009-04-10 13:52:20 -04001188extern struct ftrace_event_call __start_ftrace_events[];
1189extern struct ftrace_event_call __stop_ftrace_events[];
1190
Li Zefan020e5f82009-07-01 10:47:05 +08001191static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata;
1192
1193static __init int setup_trace_event(char *str)
1194{
1195 strlcpy(bootup_event_buf, str, COMMAND_LINE_SIZE);
1196 ring_buffer_expanded = 1;
1197 tracing_selftest_disabled = 1;
1198
1199 return 1;
1200}
1201__setup("trace_event=", setup_trace_event);
1202
Steven Rostedtb77e38a2009-02-24 10:21:36 -05001203static __init int event_trace_init(void)
1204{
Steven Rostedta59fd602009-04-10 13:52:20 -04001205 struct ftrace_event_call *call;
Steven Rostedtb77e38a2009-02-24 10:21:36 -05001206 struct dentry *d_tracer;
1207 struct dentry *entry;
Steven Rostedt1473e442009-02-24 14:15:08 -05001208 struct dentry *d_events;
Steven Rostedt6d723732009-04-10 14:53:50 -04001209 int ret;
Li Zefan020e5f82009-07-01 10:47:05 +08001210 char *buf = bootup_event_buf;
1211 char *token;
Steven Rostedtb77e38a2009-02-24 10:21:36 -05001212
1213 d_tracer = tracing_init_dentry();
1214 if (!d_tracer)
1215 return 0;
1216
Steven Rostedt2314c4a2009-03-10 12:04:02 -04001217 entry = debugfs_create_file("available_events", 0444, d_tracer,
1218 (void *)&show_event_seq_ops,
1219 &ftrace_avail_fops);
1220 if (!entry)
1221 pr_warning("Could not create debugfs "
1222 "'available_events' entry\n");
1223
Steven Rostedtb77e38a2009-02-24 10:21:36 -05001224 entry = debugfs_create_file("set_event", 0644, d_tracer,
1225 (void *)&show_set_event_seq_ops,
1226 &ftrace_set_event_fops);
1227 if (!entry)
1228 pr_warning("Could not create debugfs "
1229 "'set_event' entry\n");
1230
Steven Rostedt1473e442009-02-24 14:15:08 -05001231 d_events = event_trace_events_dir();
1232 if (!d_events)
1233 return 0;
1234
Steven Rostedtd1b182a2009-04-15 16:53:47 -04001235 /* ring buffer internal formats */
1236 trace_create_file("header_page", 0444, d_events,
1237 ring_buffer_print_page_header,
1238 &ftrace_show_header_fops);
1239
1240 trace_create_file("header_event", 0444, d_events,
1241 ring_buffer_print_entry_header,
1242 &ftrace_show_header_fops);
1243
Steven Rostedt8ae79a12009-05-06 22:52:15 -04001244 trace_create_file("enable", 0644, d_events,
Li Zefan8f31bfe2009-05-08 10:31:42 +08001245 NULL, &ftrace_system_enable_fops);
Steven Rostedt8ae79a12009-05-06 22:52:15 -04001246
Steven Rostedt6d723732009-04-10 14:53:50 -04001247 for_each_event(call, __start_ftrace_events, __stop_ftrace_events) {
Steven Rostedt1473e442009-02-24 14:15:08 -05001248 /* The linker may leave blanks */
1249 if (!call->name)
1250 continue;
Jason Baronf744bd52009-08-10 16:52:39 -04001251 if (call->raw_init) {
1252 ret = call->raw_init();
1253 if (ret < 0) {
1254 if (ret != -ENOSYS)
1255 pr_warning("Could not initialize trace "
1256 "point events/%s\n", call->name);
1257 continue;
1258 }
1259 }
Steven Rostedta59fd602009-04-10 13:52:20 -04001260 list_add(&call->list, &ftrace_events);
Steven Rostedt701970b2009-04-24 23:11:22 -04001261 event_create_dir(call, d_events, &ftrace_event_id_fops,
1262 &ftrace_enable_fops, &ftrace_event_filter_fops,
1263 &ftrace_event_format_fops);
Steven Rostedt1473e442009-02-24 14:15:08 -05001264 }
1265
Li Zefan020e5f82009-07-01 10:47:05 +08001266 while (true) {
1267 token = strsep(&buf, ",");
1268
1269 if (!token)
1270 break;
1271 if (!*token)
1272 continue;
1273
1274 ret = ftrace_set_clr_event(token, 1);
1275 if (ret)
1276 pr_warning("Failed to enable trace event: %s\n", token);
1277 }
1278
Steven Rostedt6d723732009-04-10 14:53:50 -04001279 ret = register_module_notifier(&trace_module_nb);
Ming Lei55379372009-05-18 23:04:46 +08001280 if (ret)
Steven Rostedt6d723732009-04-10 14:53:50 -04001281 pr_warning("Failed to register trace events module notifier\n");
1282
Steven Rostedtb77e38a2009-02-24 10:21:36 -05001283 return 0;
1284}
1285fs_initcall(event_trace_init);
Steven Rostedte6187002009-04-15 13:36:40 -04001286
1287#ifdef CONFIG_FTRACE_STARTUP_TEST
1288
1289static DEFINE_SPINLOCK(test_spinlock);
1290static DEFINE_SPINLOCK(test_spinlock_irq);
1291static DEFINE_MUTEX(test_mutex);
1292
1293static __init void test_work(struct work_struct *dummy)
1294{
1295 spin_lock(&test_spinlock);
1296 spin_lock_irq(&test_spinlock_irq);
1297 udelay(1);
1298 spin_unlock_irq(&test_spinlock_irq);
1299 spin_unlock(&test_spinlock);
1300
1301 mutex_lock(&test_mutex);
1302 msleep(1);
1303 mutex_unlock(&test_mutex);
1304}
1305
1306static __init int event_test_thread(void *unused)
1307{
1308 void *test_malloc;
1309
1310 test_malloc = kmalloc(1234, GFP_KERNEL);
1311 if (!test_malloc)
1312 pr_info("failed to kmalloc\n");
1313
1314 schedule_on_each_cpu(test_work);
1315
1316 kfree(test_malloc);
1317
1318 set_current_state(TASK_INTERRUPTIBLE);
1319 while (!kthread_should_stop())
1320 schedule();
1321
1322 return 0;
1323}
1324
1325/*
1326 * Do various things that may trigger events.
1327 */
1328static __init void event_test_stuff(void)
1329{
1330 struct task_struct *test_thread;
1331
1332 test_thread = kthread_run(event_test_thread, NULL, "test-events");
1333 msleep(1);
1334 kthread_stop(test_thread);
1335}
1336
1337/*
1338 * For every trace event defined, we will test each trace point separately,
1339 * and then by groups, and finally all trace points.
1340 */
Steven Rostedt9ea21c12009-04-16 12:15:44 -04001341static __init void event_trace_self_tests(void)
Steven Rostedte6187002009-04-15 13:36:40 -04001342{
1343 struct ftrace_event_call *call;
1344 struct event_subsystem *system;
Steven Rostedte6187002009-04-15 13:36:40 -04001345 int ret;
1346
1347 pr_info("Running tests on trace events:\n");
1348
1349 list_for_each_entry(call, &ftrace_events, list) {
1350
1351 /* Only test those that have a regfunc */
1352 if (!call->regfunc)
1353 continue;
1354
1355 pr_info("Testing event %s: ", call->name);
1356
1357 /*
1358 * If an event is already enabled, someone is using
1359 * it and the self test should not be on.
1360 */
1361 if (call->enabled) {
1362 pr_warning("Enabled event during self test!\n");
1363 WARN_ON_ONCE(1);
1364 continue;
1365 }
1366
Zhaolei0e907c92009-05-25 18:13:59 +08001367 ftrace_event_enable_disable(call, 1);
Steven Rostedte6187002009-04-15 13:36:40 -04001368 event_test_stuff();
Zhaolei0e907c92009-05-25 18:13:59 +08001369 ftrace_event_enable_disable(call, 0);
Steven Rostedte6187002009-04-15 13:36:40 -04001370
1371 pr_cont("OK\n");
1372 }
1373
1374 /* Now test at the sub system level */
1375
1376 pr_info("Running tests on trace event systems:\n");
1377
1378 list_for_each_entry(system, &event_subsystems, list) {
1379
1380 /* the ftrace system is special, skip it */
1381 if (strcmp(system->name, "ftrace") == 0)
1382 continue;
1383
1384 pr_info("Testing event system %s: ", system->name);
1385
Li Zefan8f31bfe2009-05-08 10:31:42 +08001386 ret = __ftrace_set_clr_event(NULL, system->name, NULL, 1);
Steven Rostedte6187002009-04-15 13:36:40 -04001387 if (WARN_ON_ONCE(ret)) {
1388 pr_warning("error enabling system %s\n",
1389 system->name);
1390 continue;
1391 }
1392
1393 event_test_stuff();
1394
Li Zefan8f31bfe2009-05-08 10:31:42 +08001395 ret = __ftrace_set_clr_event(NULL, system->name, NULL, 0);
Steven Rostedte6187002009-04-15 13:36:40 -04001396 if (WARN_ON_ONCE(ret))
1397 pr_warning("error disabling system %s\n",
1398 system->name);
1399
1400 pr_cont("OK\n");
1401 }
1402
1403 /* Test with all events enabled */
1404
1405 pr_info("Running tests on all trace events:\n");
1406 pr_info("Testing all events: ");
1407
Li Zefan8f31bfe2009-05-08 10:31:42 +08001408 ret = __ftrace_set_clr_event(NULL, NULL, NULL, 1);
Steven Rostedte6187002009-04-15 13:36:40 -04001409 if (WARN_ON_ONCE(ret)) {
Steven Rostedte6187002009-04-15 13:36:40 -04001410 pr_warning("error enabling all events\n");
Steven Rostedt9ea21c12009-04-16 12:15:44 -04001411 return;
Steven Rostedte6187002009-04-15 13:36:40 -04001412 }
1413
1414 event_test_stuff();
1415
1416 /* reset sysname */
Li Zefan8f31bfe2009-05-08 10:31:42 +08001417 ret = __ftrace_set_clr_event(NULL, NULL, NULL, 0);
Steven Rostedte6187002009-04-15 13:36:40 -04001418 if (WARN_ON_ONCE(ret)) {
1419 pr_warning("error disabling all events\n");
Steven Rostedt9ea21c12009-04-16 12:15:44 -04001420 return;
Steven Rostedte6187002009-04-15 13:36:40 -04001421 }
1422
1423 pr_cont("OK\n");
Steven Rostedt9ea21c12009-04-16 12:15:44 -04001424}
1425
1426#ifdef CONFIG_FUNCTION_TRACER
1427
1428static DEFINE_PER_CPU(atomic_t, test_event_disable);
1429
1430static void
1431function_test_events_call(unsigned long ip, unsigned long parent_ip)
1432{
1433 struct ring_buffer_event *event;
1434 struct ftrace_entry *entry;
1435 unsigned long flags;
1436 long disabled;
1437 int resched;
1438 int cpu;
1439 int pc;
1440
1441 pc = preempt_count();
1442 resched = ftrace_preempt_disable();
1443 cpu = raw_smp_processor_id();
1444 disabled = atomic_inc_return(&per_cpu(test_event_disable, cpu));
1445
1446 if (disabled != 1)
1447 goto out;
1448
1449 local_save_flags(flags);
1450
1451 event = trace_current_buffer_lock_reserve(TRACE_FN, sizeof(*entry),
1452 flags, pc);
1453 if (!event)
1454 goto out;
1455 entry = ring_buffer_event_data(event);
1456 entry->ip = ip;
1457 entry->parent_ip = parent_ip;
1458
Steven Rostedtcb4764a2009-04-20 18:16:44 -04001459 trace_nowake_buffer_unlock_commit(event, flags, pc);
Steven Rostedt9ea21c12009-04-16 12:15:44 -04001460
1461 out:
1462 atomic_dec(&per_cpu(test_event_disable, cpu));
1463 ftrace_preempt_enable(resched);
1464}
1465
1466static struct ftrace_ops trace_ops __initdata =
1467{
1468 .func = function_test_events_call,
1469};
1470
1471static __init void event_trace_self_test_with_function(void)
1472{
1473 register_ftrace_function(&trace_ops);
1474 pr_info("Running tests again, along with the function tracer\n");
1475 event_trace_self_tests();
1476 unregister_ftrace_function(&trace_ops);
1477}
1478#else
1479static __init void event_trace_self_test_with_function(void)
1480{
1481}
1482#endif
1483
1484static __init int event_trace_self_tests_init(void)
1485{
Li Zefan020e5f82009-07-01 10:47:05 +08001486 if (!tracing_selftest_disabled) {
1487 event_trace_self_tests();
1488 event_trace_self_test_with_function();
1489 }
Steven Rostedte6187002009-04-15 13:36:40 -04001490
1491 return 0;
1492}
1493
Steven Rostedt28d20e22009-04-20 12:12:44 -04001494late_initcall(event_trace_self_tests_init);
Steven Rostedte6187002009-04-15 13:36:40 -04001495
1496#endif