diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-04-10 13:52:20 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2009-04-14 12:58:00 -0400 |
commit | a59fd6027218bd7c994e39d14afe0242f895144f (patch) | |
tree | c22e6ff2924726319eac84c480eca72066bad660 /kernel | |
parent | f42c85e74faa422cf0bc747ed808681145448f88 (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')
-rw-r--r-- | kernel/trace/trace.h | 13 | ||||
-rw-r--r-- | kernel/trace/trace_event_profile.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 51 | ||||
-rw-r--r-- | kernel/trace/trace_events_filter.c | 8 |
4 files changed, 38 insertions, 38 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 6bcdf4af9b2d..8817c18ef97a 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -739,11 +739,6 @@ struct event_subsystem { | |||
739 | struct filter_pred **preds; | 739 | struct filter_pred **preds; |
740 | }; | 740 | }; |
741 | 741 | ||
742 | #define events_for_each(event) \ | ||
743 | for (event = __start_ftrace_events; \ | ||
744 | (unsigned long)event < (unsigned long)__stop_ftrace_events; \ | ||
745 | event++) | ||
746 | |||
747 | struct filter_pred; | 742 | struct filter_pred; |
748 | 743 | ||
749 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event); | 744 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event); |
@@ -785,13 +780,7 @@ filter_check_discard(struct ftrace_event_call *call, void *rec, | |||
785 | return 0; | 780 | return 0; |
786 | } | 781 | } |
787 | 782 | ||
788 | extern struct ftrace_event_call __start_ftrace_events[]; | 783 | extern struct list_head ftrace_events; |
789 | extern struct ftrace_event_call __stop_ftrace_events[]; | ||
790 | |||
791 | #define for_each_event(event) \ | ||
792 | for (event = __start_ftrace_events; \ | ||
793 | (unsigned long)event < (unsigned long)__stop_ftrace_events; \ | ||
794 | event++) | ||
795 | 784 | ||
796 | extern const char *__start___trace_bprintk_fmt[]; | 785 | extern const char *__start___trace_bprintk_fmt[]; |
797 | extern const char *__stop___trace_bprintk_fmt[]; | 786 | extern const char *__stop___trace_bprintk_fmt[]; |
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c index 199de9c74229..7bf2ad65eee5 100644 --- a/kernel/trace/trace_event_profile.c +++ b/kernel/trace/trace_event_profile.c | |||
@@ -11,7 +11,7 @@ int ftrace_profile_enable(int event_id) | |||
11 | { | 11 | { |
12 | struct ftrace_event_call *event; | 12 | struct ftrace_event_call *event; |
13 | 13 | ||
14 | for_each_event(event) { | 14 | list_for_each_entry(event, &ftrace_events, list) { |
15 | if (event->id == event_id) | 15 | if (event->id == event_id) |
16 | return event->profile_enable(event); | 16 | return event->profile_enable(event); |
17 | } | 17 | } |
@@ -23,7 +23,7 @@ void ftrace_profile_disable(int event_id) | |||
23 | { | 23 | { |
24 | struct ftrace_event_call *event; | 24 | struct ftrace_event_call *event; |
25 | 25 | ||
26 | for_each_event(event) { | 26 | list_for_each_entry(event, &ftrace_events, list) { |
27 | if (event->id == event_id) | 27 | if (event->id == event_id) |
28 | return event->profile_disable(event); | 28 | return event->profile_disable(event); |
29 | } | 29 | } |
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 | ||
20 | static DEFINE_MUTEX(event_mutex); | 20 | static DEFINE_MUTEX(event_mutex); |
21 | 21 | ||
22 | LIST_HEAD(ftrace_events); | ||
23 | |||
22 | int trace_define_field(struct ftrace_event_call *call, char *type, | 24 | int 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 | ||
55 | static void ftrace_clear_events(void) | 57 | static 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 | ||
90 | static int ftrace_set_clr_event(char *buf, int set) | 90 | static 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, | |||
224 | static void * | 224 | static void * |
225 | t_next(struct seq_file *m, void *v, loff_t *pos) | 225 | t_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) | |||
257 | static void * | 258 | static void * |
258 | s_next(struct seq_file *m, void *v, loff_t *pos) | 259 | s_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 | ||
802 | extern struct ftrace_event_call __start_ftrace_events[]; | ||
803 | extern 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 | |||
800 | static __init int event_trace_init(void) | 810 | static __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 | ||
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index de42dad42a88..d30b06b02b4d 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -223,7 +223,7 @@ oom: | |||
223 | 223 | ||
224 | void filter_free_subsystem_preds(struct event_subsystem *system) | 224 | void filter_free_subsystem_preds(struct event_subsystem *system) |
225 | { | 225 | { |
226 | struct ftrace_event_call *call = __start_ftrace_events; | 226 | struct ftrace_event_call *call; |
227 | int i; | 227 | int i; |
228 | 228 | ||
229 | if (system->n_preds) { | 229 | if (system->n_preds) { |
@@ -234,7 +234,7 @@ void filter_free_subsystem_preds(struct event_subsystem *system) | |||
234 | system->n_preds = 0; | 234 | system->n_preds = 0; |
235 | } | 235 | } |
236 | 236 | ||
237 | events_for_each(call) { | 237 | list_for_each_entry(call, &ftrace_events, list) { |
238 | if (!call->define_fields) | 238 | if (!call->define_fields) |
239 | continue; | 239 | continue; |
240 | 240 | ||
@@ -320,7 +320,7 @@ int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred) | |||
320 | int filter_add_subsystem_pred(struct event_subsystem *system, | 320 | int filter_add_subsystem_pred(struct event_subsystem *system, |
321 | struct filter_pred *pred) | 321 | struct filter_pred *pred) |
322 | { | 322 | { |
323 | struct ftrace_event_call *call = __start_ftrace_events; | 323 | struct ftrace_event_call *call; |
324 | 324 | ||
325 | if (system->n_preds && !pred->compound) | 325 | if (system->n_preds && !pred->compound) |
326 | filter_free_subsystem_preds(system); | 326 | filter_free_subsystem_preds(system); |
@@ -337,7 +337,7 @@ int filter_add_subsystem_pred(struct event_subsystem *system, | |||
337 | 337 | ||
338 | system->preds[system->n_preds] = pred; | 338 | system->preds[system->n_preds] = pred; |
339 | 339 | ||
340 | events_for_each(call) { | 340 | list_for_each_entry(call, &ftrace_events, list) { |
341 | int err; | 341 | int err; |
342 | 342 | ||
343 | if (!call->define_fields) | 343 | if (!call->define_fields) |