diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2009-08-31 04:49:41 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-08-31 04:58:08 -0400 |
commit | 8e254c1d183f0225ad21f9049641529e56cce4da (patch) | |
tree | 5b559726a38b60c6bc92b3c8667c676db1038701 /kernel | |
parent | 73222acf966792c7fda219724af963339be32e62 (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.c | 50 | ||||
-rw-r--r-- | kernel/trace/trace_export.c | 1 |
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 | ||
403 | int init_preds(struct ftrace_event_call *call) | 406 | static 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 | } |
435 | EXPORT_SYMBOL_GPL(init_preds); | 437 | |
438 | static 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 | ||
437 | enum { | 460 | enum { |
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 = { \ | |||
135 | static int ftrace_raw_init_event_##call(void) \ | 135 | static 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 | ||