aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_events.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-04-10 13:52:20 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-04-14 12:58:00 -0400
commita59fd6027218bd7c994e39d14afe0242f895144f (patch)
treec22e6ff2924726319eac84c480eca72066bad660 /kernel/trace/trace_events.c
parentf42c85e74faa422cf0bc747ed808681145448f88 (diff)
tracing/events: convert event call sites to use a link list
Impact: makes it possible to define events in modules The events are created by reading down the section that they are linked in by the macros. But this is not scalable to modules. This patch converts the manipulations to use a global link list, and on boot up it adds the items in the section to the list. This change will allow modules to add their tracing events to the list as well. Note, this change alone does not permit modules to use the TRACE_EVENT macros, but the change is needed for them to eventually do so. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_events.c')
-rw-r--r--kernel/trace/trace_events.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index ead68ac99191..5c66aaff07c1 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -19,6 +19,8 @@
19 19
20static DEFINE_MUTEX(event_mutex); 20static DEFINE_MUTEX(event_mutex);
21 21
22LIST_HEAD(ftrace_events);
23
22int trace_define_field(struct ftrace_event_call *call, char *type, 24int trace_define_field(struct ftrace_event_call *call, char *type,
23 char *name, int offset, int size) 25 char *name, int offset, int size)
24{ 26{
@@ -54,16 +56,14 @@ err:
54 56
55static void ftrace_clear_events(void) 57static void ftrace_clear_events(void)
56{ 58{
57 struct ftrace_event_call *call = (void *)__start_ftrace_events; 59 struct ftrace_event_call *call;
58
59 60
60 while ((unsigned long)call < (unsigned long)__stop_ftrace_events) { 61 list_for_each_entry(call, &ftrace_events, list) {
61 62
62 if (call->enabled) { 63 if (call->enabled) {
63 call->enabled = 0; 64 call->enabled = 0;
64 call->unregfunc(); 65 call->unregfunc();
65 } 66 }
66 call++;
67 } 67 }
68} 68}
69 69
@@ -89,7 +89,7 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call,
89 89
90static int ftrace_set_clr_event(char *buf, int set) 90static int ftrace_set_clr_event(char *buf, int set)
91{ 91{
92 struct ftrace_event_call *call = __start_ftrace_events; 92 struct ftrace_event_call *call;
93 char *event = NULL, *sub = NULL, *match; 93 char *event = NULL, *sub = NULL, *match;
94 int ret = -EINVAL; 94 int ret = -EINVAL;
95 95
@@ -118,7 +118,7 @@ static int ftrace_set_clr_event(char *buf, int set)
118 } 118 }
119 119
120 mutex_lock(&event_mutex); 120 mutex_lock(&event_mutex);
121 for_each_event(call) { 121 list_for_each_entry(call, &ftrace_events, list) {
122 122
123 if (!call->name || !call->regfunc) 123 if (!call->name || !call->regfunc)
124 continue; 124 continue;
@@ -224,15 +224,17 @@ ftrace_event_write(struct file *file, const char __user *ubuf,
224static void * 224static void *
225t_next(struct seq_file *m, void *v, loff_t *pos) 225t_next(struct seq_file *m, void *v, loff_t *pos)
226{ 226{
227 struct ftrace_event_call *call = m->private; 227 struct list_head *list = m->private;
228 struct ftrace_event_call *next = call; 228 struct ftrace_event_call *call;
229 229
230 (*pos)++; 230 (*pos)++;
231 231
232 for (;;) { 232 for (;;) {
233 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events) 233 if (list == &ftrace_events)
234 return NULL; 234 return NULL;
235 235
236 call = list_entry(list, struct ftrace_event_call, list);
237
236 /* 238 /*
237 * The ftrace subsystem is for showing formats only. 239 * The ftrace subsystem is for showing formats only.
238 * They can not be enabled or disabled via the event files. 240 * They can not be enabled or disabled via the event files.
@@ -240,11 +242,10 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
240 if (call->regfunc) 242 if (call->regfunc)
241 break; 243 break;
242 244
243 call++; 245 list = list->next;
244 next = call;
245 } 246 }
246 247
247 m->private = ++next; 248 m->private = list->next;
248 249
249 return call; 250 return call;
250} 251}
@@ -257,22 +258,23 @@ static void *t_start(struct seq_file *m, loff_t *pos)
257static void * 258static void *
258s_next(struct seq_file *m, void *v, loff_t *pos) 259s_next(struct seq_file *m, void *v, loff_t *pos)
259{ 260{
260 struct ftrace_event_call *call = m->private; 261 struct list_head *list = m->private;
261 struct ftrace_event_call *next; 262 struct ftrace_event_call *call;
262 263
263 (*pos)++; 264 (*pos)++;
264 265
265 retry: 266 retry:
266 if ((unsigned long)call >= (unsigned long)__stop_ftrace_events) 267 if (list == &ftrace_events)
267 return NULL; 268 return NULL;
268 269
270 call = list_entry(list, struct ftrace_event_call, list);
271
269 if (!call->enabled) { 272 if (!call->enabled) {
270 call++; 273 list = list->next;
271 goto retry; 274 goto retry;
272 } 275 }
273 276
274 next = call; 277 m->private = list->next;
275 m->private = ++next;
276 278
277 return call; 279 return call;
278} 280}
@@ -312,7 +314,7 @@ ftrace_event_seq_open(struct inode *inode, struct file *file)
312 if (!ret) { 314 if (!ret) {
313 struct seq_file *m = file->private_data; 315 struct seq_file *m = file->private_data;
314 316
315 m->private = __start_ftrace_events; 317 m->private = ftrace_events.next;
316 } 318 }
317 return ret; 319 return ret;
318} 320}
@@ -797,9 +799,17 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
797 return 0; 799 return 0;
798} 800}
799 801
802extern struct ftrace_event_call __start_ftrace_events[];
803extern struct ftrace_event_call __stop_ftrace_events[];
804
805#define for_each_event(event) \
806 for (event = __start_ftrace_events; \
807 (unsigned long)event < (unsigned long)__stop_ftrace_events; \
808 event++)
809
800static __init int event_trace_init(void) 810static __init int event_trace_init(void)
801{ 811{
802 struct ftrace_event_call *call = __start_ftrace_events; 812 struct ftrace_event_call *call;
803 struct dentry *d_tracer; 813 struct dentry *d_tracer;
804 struct dentry *entry; 814 struct dentry *entry;
805 struct dentry *d_events; 815 struct dentry *d_events;
@@ -830,6 +840,7 @@ static __init int event_trace_init(void)
830 /* The linker may leave blanks */ 840 /* The linker may leave blanks */
831 if (!call->name) 841 if (!call->name)
832 continue; 842 continue;
843 list_add(&call->list, &ftrace_events);
833 event_create_dir(call, d_events); 844 event_create_dir(call, d_events);
834 } 845 }
835 846