Commit 8e254c1d authored by Li Zefan's avatar Li Zefan Committed by Ingo Molnar

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: default avatarLi 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: default avatarIngo Molnar <mingo@elte.hu>
parent 73222acf
...@@ -133,7 +133,6 @@ struct ftrace_event_call { ...@@ -133,7 +133,6 @@ struct ftrace_event_call {
#define MAX_FILTER_PRED 32 #define MAX_FILTER_PRED 32
#define MAX_FILTER_STR_VAL 128 #define MAX_FILTER_STR_VAL 128
extern int init_preds(struct ftrace_event_call *call);
extern void destroy_preds(struct ftrace_event_call *call); extern void destroy_preds(struct ftrace_event_call *call);
extern int filter_match_preds(struct ftrace_event_call *call, void *rec); extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
extern int filter_current_check_discard(struct ftrace_event_call *call, extern int filter_current_check_discard(struct ftrace_event_call *call,
......
...@@ -177,7 +177,6 @@ static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \ ...@@ -177,7 +177,6 @@ static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \
event_enter_##sname.id = id; \ event_enter_##sname.id = id; \
set_syscall_enter_id(num, id); \ set_syscall_enter_id(num, id); \
INIT_LIST_HEAD(&event_enter_##sname.fields); \ INIT_LIST_HEAD(&event_enter_##sname.fields); \
init_preds(&event_enter_##sname); \
return 0; \ return 0; \
} \ } \
TRACE_SYS_ENTER_PROFILE(sname); \ TRACE_SYS_ENTER_PROFILE(sname); \
...@@ -214,7 +213,6 @@ static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \ ...@@ -214,7 +213,6 @@ static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \
event_exit_##sname.id = id; \ event_exit_##sname.id = id; \
set_syscall_exit_id(num, id); \ set_syscall_exit_id(num, id); \
INIT_LIST_HEAD(&event_exit_##sname.fields); \ INIT_LIST_HEAD(&event_exit_##sname.fields); \
init_preds(&event_exit_##sname); \
return 0; \ return 0; \
} \ } \
TRACE_SYS_EXIT_PROFILE(sname); \ TRACE_SYS_EXIT_PROFILE(sname); \
......
...@@ -622,7 +622,6 @@ static int ftrace_raw_init_event_##call(void) \ ...@@ -622,7 +622,6 @@ static int ftrace_raw_init_event_##call(void) \
return -ENODEV; \ return -ENODEV; \
event_##call.id = id; \ event_##call.id = id; \
INIT_LIST_HEAD(&event_##call.fields); \ INIT_LIST_HEAD(&event_##call.fields); \
init_preds(&event_##call); \
return 0; \ return 0; \
} \ } \
\ \
......
...@@ -309,7 +309,7 @@ void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s) ...@@ -309,7 +309,7 @@ void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s)
struct event_filter *filter = call->filter; struct event_filter *filter = call->filter;
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
if (filter->filter_string) if (filter && filter->filter_string)
trace_seq_printf(s, "%s\n", filter->filter_string); trace_seq_printf(s, "%s\n", filter->filter_string);
else else
trace_seq_printf(s, "none\n"); trace_seq_printf(s, "none\n");
...@@ -322,7 +322,7 @@ void print_subsystem_event_filter(struct event_subsystem *system, ...@@ -322,7 +322,7 @@ void print_subsystem_event_filter(struct event_subsystem *system,
struct event_filter *filter = system->filter; struct event_filter *filter = system->filter;
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
if (filter->filter_string) if (filter && filter->filter_string)
trace_seq_printf(s, "%s\n", filter->filter_string); trace_seq_printf(s, "%s\n", filter->filter_string);
else else
trace_seq_printf(s, "none\n"); trace_seq_printf(s, "none\n");
...@@ -390,6 +390,9 @@ void destroy_preds(struct ftrace_event_call *call) ...@@ -390,6 +390,9 @@ void destroy_preds(struct ftrace_event_call *call)
struct event_filter *filter = call->filter; struct event_filter *filter = call->filter;
int i; int i;
if (!filter)
return;
for (i = 0; i < MAX_FILTER_PRED; i++) { for (i = 0; i < MAX_FILTER_PRED; i++) {
if (filter->preds[i]) if (filter->preds[i])
filter_free_pred(filter->preds[i]); filter_free_pred(filter->preds[i]);
...@@ -400,7 +403,7 @@ void destroy_preds(struct ftrace_event_call *call) ...@@ -400,7 +403,7 @@ void destroy_preds(struct ftrace_event_call *call)
call->filter = NULL; call->filter = NULL;
} }
int init_preds(struct ftrace_event_call *call) static int init_preds(struct ftrace_event_call *call)
{ {
struct event_filter *filter; struct event_filter *filter;
struct filter_pred *pred; struct filter_pred *pred;
...@@ -410,7 +413,6 @@ int init_preds(struct ftrace_event_call *call) ...@@ -410,7 +413,6 @@ int init_preds(struct ftrace_event_call *call)
if (!call->filter) if (!call->filter)
return -ENOMEM; return -ENOMEM;
call->filter_active = 0;
filter->n_preds = 0; filter->n_preds = 0;
filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL); filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL);
...@@ -432,7 +434,28 @@ oom: ...@@ -432,7 +434,28 @@ oom:
return -ENOMEM; return -ENOMEM;
} }
EXPORT_SYMBOL_GPL(init_preds);
static int init_subsystem_preds(struct event_subsystem *system)
{
struct ftrace_event_call *call;
int err;
list_for_each_entry(call, &ftrace_events, list) {
if (!call->define_fields)
continue;
if (strcmp(call->system, system->name) != 0)
continue;
if (!call->filter) {
err = init_preds(call);
if (err)
return err;
}
}
return 0;
}
enum { enum {
FILTER_DISABLE_ALL, FILTER_DISABLE_ALL,
...@@ -449,6 +472,9 @@ static void filter_free_subsystem_preds(struct event_subsystem *system, ...@@ -449,6 +472,9 @@ static void filter_free_subsystem_preds(struct event_subsystem *system,
if (!call->define_fields) if (!call->define_fields)
continue; continue;
if (strcmp(call->system, system->name) != 0)
continue;
if (flag == FILTER_INIT_NO_RESET) { if (flag == FILTER_INIT_NO_RESET) {
call->filter->no_reset = false; call->filter->no_reset = false;
continue; continue;
...@@ -457,10 +483,8 @@ static void filter_free_subsystem_preds(struct event_subsystem *system, ...@@ -457,10 +483,8 @@ static void filter_free_subsystem_preds(struct event_subsystem *system,
if (flag == FILTER_SKIP_NO_RESET && call->filter->no_reset) if (flag == FILTER_SKIP_NO_RESET && call->filter->no_reset)
continue; continue;
if (!strcmp(call->system, system->name)) { filter_disable_preds(call);
filter_disable_preds(call); remove_filter_string(call->filter);
remove_filter_string(call->filter);
}
} }
} }
...@@ -1094,6 +1118,10 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string) ...@@ -1094,6 +1118,10 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
err = init_preds(call);
if (err)
goto out_unlock;
if (!strcmp(strstrip(filter_string), "0")) { if (!strcmp(strstrip(filter_string), "0")) {
filter_disable_preds(call); filter_disable_preds(call);
remove_filter_string(call->filter); remove_filter_string(call->filter);
...@@ -1139,6 +1167,10 @@ int apply_subsystem_event_filter(struct event_subsystem *system, ...@@ -1139,6 +1167,10 @@ int apply_subsystem_event_filter(struct event_subsystem *system,
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
err = init_subsystem_preds(system);
if (err)
goto out_unlock;
if (!strcmp(strstrip(filter_string), "0")) { if (!strcmp(strstrip(filter_string), "0")) {
filter_free_subsystem_preds(system, FILTER_DISABLE_ALL); filter_free_subsystem_preds(system, FILTER_DISABLE_ALL);
remove_filter_string(system->filter); remove_filter_string(system->filter);
......
...@@ -135,7 +135,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ ...@@ -135,7 +135,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
static int ftrace_raw_init_event_##call(void) \ static int ftrace_raw_init_event_##call(void) \
{ \ { \
INIT_LIST_HEAD(&event_##call.fields); \ INIT_LIST_HEAD(&event_##call.fields); \
init_preds(&event_##call); \
return 0; \ return 0; \
} \ } \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment