aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLi Zefan <lizf@cn.fujitsu.com>2009-08-31 04:49:41 -0400
committerIngo Molnar <mingo@elte.hu>2009-08-31 04:58:08 -0400
commit8e254c1d183f0225ad21f9049641529e56cce4da (patch)
tree5b559726a38b60c6bc92b3c8667c676db1038701 /kernel
parent73222acf966792c7fda219724af963339be32e62 (diff)
tracing/filters: Defer pred allocation
init_preds() allocates about 5392 bytes of memory (on x86_32) for a TRACE_EVENT. With my config, at system boot total memory occupied is: 5392 * (642 + 15) == 3459KB 642 == cat available_events | wc -l 15 == number of dirs in events/ftrace That's quite a lot, so we'd better defer memory allocation util it's needed, that's when filter is used. Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Tom Zanussi <tzanussi@gmail.com> Cc: Masami Hiramatsu <mhiramat@redhat.com> LKML-Reference: <4A9B8EA5.6020700@cn.fujitsu.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace_events_filter.c50
-rw-r--r--kernel/trace/trace_export.c1
2 files changed, 41 insertions, 10 deletions
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 9f03082c81d8..c6b2edfb7fe9 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -309,7 +309,7 @@ void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s)
309 struct event_filter *filter = call->filter; 309 struct event_filter *filter = call->filter;
310 310
311 mutex_lock(&event_mutex); 311 mutex_lock(&event_mutex);
312 if (filter->filter_string) 312 if (filter && filter->filter_string)
313 trace_seq_printf(s, "%s\n", filter->filter_string); 313 trace_seq_printf(s, "%s\n", filter->filter_string);
314 else 314 else
315 trace_seq_printf(s, "none\n"); 315 trace_seq_printf(s, "none\n");
@@ -322,7 +322,7 @@ void print_subsystem_event_filter(struct event_subsystem *system,
322 struct event_filter *filter = system->filter; 322 struct event_filter *filter = system->filter;
323 323
324 mutex_lock(&event_mutex); 324 mutex_lock(&event_mutex);
325 if (filter->filter_string) 325 if (filter && filter->filter_string)
326 trace_seq_printf(s, "%s\n", filter->filter_string); 326 trace_seq_printf(s, "%s\n", filter->filter_string);
327 else 327 else
328 trace_seq_printf(s, "none\n"); 328 trace_seq_printf(s, "none\n");
@@ -390,6 +390,9 @@ void destroy_preds(struct ftrace_event_call *call)
390 struct event_filter *filter = call->filter; 390 struct event_filter *filter = call->filter;
391 int i; 391 int i;
392 392
393 if (!filter)
394 return;
395
393 for (i = 0; i < MAX_FILTER_PRED; i++) { 396 for (i = 0; i < MAX_FILTER_PRED; i++) {
394 if (filter->preds[i]) 397 if (filter->preds[i])
395 filter_free_pred(filter->preds[i]); 398 filter_free_pred(filter->preds[i]);
@@ -400,7 +403,7 @@ void destroy_preds(struct ftrace_event_call *call)
400 call->filter = NULL; 403 call->filter = NULL;
401} 404}
402 405
403int init_preds(struct ftrace_event_call *call) 406static int init_preds(struct ftrace_event_call *call)
404{ 407{
405 struct event_filter *filter; 408 struct event_filter *filter;
406 struct filter_pred *pred; 409 struct filter_pred *pred;
@@ -410,7 +413,6 @@ int init_preds(struct ftrace_event_call *call)
410 if (!call->filter) 413 if (!call->filter)
411 return -ENOMEM; 414 return -ENOMEM;
412 415
413 call->filter_active = 0;
414 filter->n_preds = 0; 416 filter->n_preds = 0;
415 417
416 filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL); 418 filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL);
@@ -432,7 +434,28 @@ oom:
432 434
433 return -ENOMEM; 435 return -ENOMEM;
434} 436}
435EXPORT_SYMBOL_GPL(init_preds); 437
438static int init_subsystem_preds(struct event_subsystem *system)
439{
440 struct ftrace_event_call *call;
441 int err;
442
443 list_for_each_entry(call, &ftrace_events, list) {
444 if (!call->define_fields)
445 continue;
446
447 if (strcmp(call->system, system->name) != 0)
448 continue;
449
450 if (!call->filter) {
451 err = init_preds(call);
452 if (err)
453 return err;
454 }
455 }
456
457 return 0;
458}
436 459
437enum { 460enum {
438 FILTER_DISABLE_ALL, 461 FILTER_DISABLE_ALL,
@@ -449,6 +472,9 @@ static void filter_free_subsystem_preds(struct event_subsystem *system,
449 if (!call->define_fields) 472 if (!call->define_fields)
450 continue; 473 continue;
451 474
475 if (strcmp(call->system, system->name) != 0)
476 continue;
477
452 if (flag == FILTER_INIT_NO_RESET) { 478 if (flag == FILTER_INIT_NO_RESET) {
453 call->filter->no_reset = false; 479 call->filter->no_reset = false;
454 continue; 480 continue;
@@ -457,10 +483,8 @@ static void filter_free_subsystem_preds(struct event_subsystem *system,
457 if (flag == FILTER_SKIP_NO_RESET && call->filter->no_reset) 483 if (flag == FILTER_SKIP_NO_RESET && call->filter->no_reset)
458 continue; 484 continue;
459 485
460 if (!strcmp(call->system, system->name)) { 486 filter_disable_preds(call);
461 filter_disable_preds(call); 487 remove_filter_string(call->filter);
462 remove_filter_string(call->filter);
463 }
464 } 488 }
465} 489}
466 490
@@ -1094,6 +1118,10 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
1094 1118
1095 mutex_lock(&event_mutex); 1119 mutex_lock(&event_mutex);
1096 1120
1121 err = init_preds(call);
1122 if (err)
1123 goto out_unlock;
1124
1097 if (!strcmp(strstrip(filter_string), "0")) { 1125 if (!strcmp(strstrip(filter_string), "0")) {
1098 filter_disable_preds(call); 1126 filter_disable_preds(call);
1099 remove_filter_string(call->filter); 1127 remove_filter_string(call->filter);
@@ -1139,6 +1167,10 @@ int apply_subsystem_event_filter(struct event_subsystem *system,
1139 1167
1140 mutex_lock(&event_mutex); 1168 mutex_lock(&event_mutex);
1141 1169
1170 err = init_subsystem_preds(system);
1171 if (err)
1172 goto out_unlock;
1173
1142 if (!strcmp(strstrip(filter_string), "0")) { 1174 if (!strcmp(strstrip(filter_string), "0")) {
1143 filter_free_subsystem_preds(system, FILTER_DISABLE_ALL); 1175 filter_free_subsystem_preds(system, FILTER_DISABLE_ALL);
1144 remove_filter_string(system->filter); 1176 remove_filter_string(system->filter);
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index 029a91f42287..df1bf6e48bb9 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -135,7 +135,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
135static int ftrace_raw_init_event_##call(void) \ 135static int ftrace_raw_init_event_##call(void) \
136{ \ 136{ \
137 INIT_LIST_HEAD(&event_##call.fields); \ 137 INIT_LIST_HEAD(&event_##call.fields); \
138 init_preds(&event_##call); \
139 return 0; \ 138 return 0; \
140} \ 139} \
141 140