Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -133,7 +133,6 @@ struct ftrace_event_call {
#define MAX_FILTER_PRED		32
#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 int filter_match_preds(struct ftrace_event_call *call, void *rec);
extern int filter_current_check_discard(struct ftrace_event_call *call,
+0 −2
Original line number Diff line number Diff line
@@ -177,7 +177,6 @@ static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \
		event_enter_##sname.id = id;				\
		set_syscall_enter_id(num, id);				\
		INIT_LIST_HEAD(&event_enter_##sname.fields);		\
		init_preds(&event_enter_##sname);			\
		return 0;						\
	}								\
	TRACE_SYS_ENTER_PROFILE(sname);					\
@@ -214,7 +213,6 @@ static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \
		event_exit_##sname.id = id;				\
		set_syscall_exit_id(num, id);				\
		INIT_LIST_HEAD(&event_exit_##sname.fields);		\
		init_preds(&event_exit_##sname);			\
		return 0;						\
	}								\
	TRACE_SYS_EXIT_PROFILE(sname);					\
+0 −1
Original line number Diff line number Diff line
@@ -622,7 +622,6 @@ static int ftrace_raw_init_event_##call(void) \
		return -ENODEV;						\
	event_##call.id = id;						\
	INIT_LIST_HEAD(&event_##call.fields);				\
	init_preds(&event_##call);					\
	return 0;							\
}									\
									\
+41 −9
Original line number Diff line number Diff line
@@ -309,7 +309,7 @@ void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s)
	struct event_filter *filter = call->filter;

	mutex_lock(&event_mutex);
	if (filter->filter_string)
	if (filter && filter->filter_string)
		trace_seq_printf(s, "%s\n", filter->filter_string);
	else
		trace_seq_printf(s, "none\n");
@@ -322,7 +322,7 @@ void print_subsystem_event_filter(struct event_subsystem *system,
	struct event_filter *filter = system->filter;

	mutex_lock(&event_mutex);
	if (filter->filter_string)
	if (filter && filter->filter_string)
		trace_seq_printf(s, "%s\n", filter->filter_string);
	else
		trace_seq_printf(s, "none\n");
@@ -390,6 +390,9 @@ void destroy_preds(struct ftrace_event_call *call)
	struct event_filter *filter = call->filter;
	int i;

	if (!filter)
		return;

	for (i = 0; i < MAX_FILTER_PRED; i++) {
		if (filter->preds[i])
			filter_free_pred(filter->preds[i]);
@@ -400,7 +403,7 @@ void destroy_preds(struct ftrace_event_call *call)
	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 filter_pred *pred;
@@ -410,7 +413,6 @@ int init_preds(struct ftrace_event_call *call)
	if (!call->filter)
		return -ENOMEM;

	call->filter_active = 0;
	filter->n_preds = 0;

	filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL);
@@ -432,7 +434,28 @@ oom:

	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 {
	FILTER_DISABLE_ALL,
@@ -449,6 +472,9 @@ static void filter_free_subsystem_preds(struct event_subsystem *system,
		if (!call->define_fields)
			continue;

		if (strcmp(call->system, system->name) != 0)
			continue;

		if (flag == FILTER_INIT_NO_RESET) {
			call->filter->no_reset = false;
			continue;
@@ -457,12 +483,10 @@ static void filter_free_subsystem_preds(struct event_subsystem *system,
		if (flag == FILTER_SKIP_NO_RESET && call->filter->no_reset)
			continue;

		if (!strcmp(call->system, system->name)) {
		filter_disable_preds(call);
		remove_filter_string(call->filter);
	}
}
}

static int filter_add_pred_fn(struct filter_parse_state *ps,
			      struct ftrace_event_call *call,
@@ -1094,6 +1118,10 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)

	mutex_lock(&event_mutex);

	err = init_preds(call);
	if (err)
		goto out_unlock;

	if (!strcmp(strstrip(filter_string), "0")) {
		filter_disable_preds(call);
		remove_filter_string(call->filter);
@@ -1139,6 +1167,10 @@ int apply_subsystem_event_filter(struct event_subsystem *system,

	mutex_lock(&event_mutex);

	err = init_subsystem_preds(system);
	if (err)
		goto out_unlock;

	if (!strcmp(strstrip(filter_string), "0")) {
		filter_free_subsystem_preds(system, FILTER_DISABLE_ALL);
		remove_filter_string(system->filter);
+0 −1
Original line number Diff line number Diff line
@@ -135,7 +135,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
static int ftrace_raw_init_event_##call(void)				\
{									\
	INIT_LIST_HEAD(&event_##call.fields);				\
	init_preds(&event_##call);					\
	return 0;							\
}									\