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

Commit 30e673b2 authored by Tom Zanussi's avatar Tom Zanussi Committed by Ingo Molnar
Browse files

tracing/filters: move preds into event_filter object



Create a new event_filter object, and move the pred-related members
out of the call and subsystem objects and into the filter object - the
details of the filter implementation don't need to be exposed in the
call and subsystem in any case, and it will also help make the new
parser implementation a little cleaner.

[ Impact: refactor trace-filter code to prepare for new features ]

Signed-off-by: default avatarTom Zanussi <tzanussi@gmail.com>
Acked-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Cc: fweisbec@gmail.com
Cc: Li Zefan <lizf@cn.fujitsu.com>
LKML-Reference: <1240905887.6416.119.camel@tropicana>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 0f9a623d
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -101,8 +101,8 @@ struct ftrace_event_call {
	int			(*show_format)(struct trace_seq *s);
	int			(*show_format)(struct trace_seq *s);
	int			(*define_fields)(void);
	int			(*define_fields)(void);
	struct list_head	fields;
	struct list_head	fields;
	int			n_preds;
	int			filter_active;
	struct filter_pred	**preds;
	void			*filter;
	void			*mod;
	void			*mod;


#ifdef CONFIG_EVENT_PROFILE
#ifdef CONFIG_EVENT_PROFILE
+7 −3
Original line number Original line Diff line number Diff line
@@ -731,12 +731,16 @@ struct ftrace_event_field {
	int			size;
	int			size;
};
};


struct event_filter {
	int			n_preds;
	struct filter_pred	**preds;
};

struct event_subsystem {
struct event_subsystem {
	struct list_head	list;
	struct list_head	list;
	const char		*name;
	const char		*name;
	struct dentry		*entry;
	struct dentry		*entry;
	int			n_preds;
	void			*filter;
	struct filter_pred	**preds;
};
};


struct filter_pred;
struct filter_pred;
@@ -774,7 +778,7 @@ filter_check_discard(struct ftrace_event_call *call, void *rec,
		     struct ring_buffer *buffer,
		     struct ring_buffer *buffer,
		     struct ring_buffer_event *event)
		     struct ring_buffer_event *event)
{
{
	if (unlikely(call->n_preds) && !filter_match_preds(call, rec)) {
	if (unlikely(call->filter_active) && !filter_match_preds(call, rec)) {
		ring_buffer_discard_commit(buffer, event);
		ring_buffer_discard_commit(buffer, event);
		return 1;
		return 1;
	}
	}
+1 −2
Original line number Original line Diff line number Diff line
@@ -757,8 +757,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events)


	list_add(&system->list, &event_subsystems);
	list_add(&system->list, &event_subsystems);


	system->preds = NULL;
	system->filter = NULL;
	system->n_preds = 0;


	entry = debugfs_create_file("filter", 0644, system->entry, system,
	entry = debugfs_create_file("filter", 0644, system->entry, system,
				    &ftrace_subsystem_filter_fops);
				    &ftrace_subsystem_filter_fops);
+66 −41
Original line number Original line Diff line number Diff line
@@ -93,11 +93,12 @@ static int filter_pred_none(struct filter_pred *pred, void *event)
/* return 1 if event matches, 0 otherwise (discard) */
/* return 1 if event matches, 0 otherwise (discard) */
int filter_match_preds(struct ftrace_event_call *call, void *rec)
int filter_match_preds(struct ftrace_event_call *call, void *rec)
{
{
	struct event_filter *filter = call->filter;
	int i, matched, and_failed = 0;
	int i, matched, and_failed = 0;
	struct filter_pred *pred;
	struct filter_pred *pred;


	for (i = 0; i < call->n_preds; i++) {
	for (i = 0; i < filter->n_preds; i++) {
		pred = call->preds[i];
		pred = filter->preds[i];
		if (and_failed && !pred->or)
		if (and_failed && !pred->or)
			continue;
			continue;
		matched = pred->fn(pred, rec);
		matched = pred->fn(pred, rec);
@@ -115,20 +116,20 @@ int filter_match_preds(struct ftrace_event_call *call, void *rec)
}
}
EXPORT_SYMBOL_GPL(filter_match_preds);
EXPORT_SYMBOL_GPL(filter_match_preds);


static void __filter_print_preds(struct filter_pred **preds, int n_preds,
static void __filter_print_preds(struct event_filter *filter,
				 struct trace_seq *s)
				 struct trace_seq *s)
{
{
	char *field_name;
	struct filter_pred *pred;
	struct filter_pred *pred;
	char *field_name;
	int i;
	int i;


	if (!n_preds) {
	if (!filter || !filter->n_preds) {
		trace_seq_printf(s, "none\n");
		trace_seq_printf(s, "none\n");
		return;
		return;
	}
	}


	for (i = 0; i < n_preds; i++) {
	for (i = 0; i < filter->n_preds; i++) {
		pred = preds[i];
		pred = filter->preds[i];
		field_name = pred->field_name;
		field_name = pred->field_name;
		if (i)
		if (i)
			trace_seq_printf(s, pred->or ? "|| " : "&& ");
			trace_seq_printf(s, pred->or ? "|| " : "&& ");
@@ -144,7 +145,7 @@ static void __filter_print_preds(struct filter_pred **preds, int n_preds,
void filter_print_preds(struct ftrace_event_call *call, struct trace_seq *s)
void filter_print_preds(struct ftrace_event_call *call, struct trace_seq *s)
{
{
	mutex_lock(&filter_mutex);
	mutex_lock(&filter_mutex);
	__filter_print_preds(call->preds, call->n_preds, s);
	__filter_print_preds(call->filter, s);
	mutex_unlock(&filter_mutex);
	mutex_unlock(&filter_mutex);
}
}


@@ -152,7 +153,7 @@ void filter_print_subsystem_preds(struct event_subsystem *system,
				  struct trace_seq *s)
				  struct trace_seq *s)
{
{
	mutex_lock(&filter_mutex);
	mutex_lock(&filter_mutex);
	__filter_print_preds(system->preds, system->n_preds, s);
	__filter_print_preds(system->filter, s);
	mutex_unlock(&filter_mutex);
	mutex_unlock(&filter_mutex);
}
}


@@ -200,12 +201,14 @@ static int filter_set_pred(struct filter_pred *dest,


static void __filter_disable_preds(struct ftrace_event_call *call)
static void __filter_disable_preds(struct ftrace_event_call *call)
{
{
	struct event_filter *filter = call->filter;
	int i;
	int i;


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


	for (i = 0; i < MAX_FILTER_PRED; i++)
	for (i = 0; i < MAX_FILTER_PRED; i++)
		call->preds[i]->fn = filter_pred_none;
		filter->preds[i]->fn = filter_pred_none;
}
}


void filter_disable_preds(struct ftrace_event_call *call)
void filter_disable_preds(struct ftrace_event_call *call)
@@ -217,32 +220,39 @@ void filter_disable_preds(struct ftrace_event_call *call)


int init_preds(struct ftrace_event_call *call)
int init_preds(struct ftrace_event_call *call)
{
{
	struct event_filter *filter;
	struct filter_pred *pred;
	struct filter_pred *pred;
	int i;
	int i;


	call->n_preds = 0;
	filter = call->filter = kzalloc(sizeof(*filter), GFP_KERNEL);

	if (!call->filter)
	call->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL);
	if (!call->preds)
		return -ENOMEM;
		return -ENOMEM;


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

	filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL);
	if (!filter->preds)
		goto oom;

	for (i = 0; i < MAX_FILTER_PRED; i++) {
	for (i = 0; i < MAX_FILTER_PRED; i++) {
		pred = kzalloc(sizeof(*pred), GFP_KERNEL);
		pred = kzalloc(sizeof(*pred), GFP_KERNEL);
		if (!pred)
		if (!pred)
			goto oom;
			goto oom;
		pred->fn = filter_pred_none;
		pred->fn = filter_pred_none;
		call->preds[i] = pred;
		filter->preds[i] = pred;
	}
	}


	return 0;
	return 0;


oom:
oom:
	for (i = 0; i < MAX_FILTER_PRED; i++) {
	for (i = 0; i < MAX_FILTER_PRED; i++) {
		if (call->preds[i])
		if (filter->preds[i])
			filter_free_pred(call->preds[i]);
			filter_free_pred(filter->preds[i]);
	}
	}
	kfree(call->preds);
	kfree(filter->preds);
	call->preds = NULL;
	kfree(call->filter);
	call->filter = NULL;


	return -ENOMEM;
	return -ENOMEM;
}
}
@@ -250,15 +260,16 @@ EXPORT_SYMBOL_GPL(init_preds);


static void __filter_free_subsystem_preds(struct event_subsystem *system)
static void __filter_free_subsystem_preds(struct event_subsystem *system)
{
{
	struct event_filter *filter = system->filter;
	struct ftrace_event_call *call;
	struct ftrace_event_call *call;
	int i;
	int i;


	if (system->n_preds) {
	if (filter && filter->n_preds) {
		for (i = 0; i < system->n_preds; i++)
		for (i = 0; i < filter->n_preds; i++)
			filter_free_pred(system->preds[i]);
			filter_free_pred(filter->preds[i]);
		kfree(system->preds);
		kfree(filter->preds);
		system->preds = NULL;
		kfree(filter);
		system->n_preds = 0;
		system->filter = NULL;
	}
	}


	list_for_each_entry(call, &ftrace_events, list) {
	list_for_each_entry(call, &ftrace_events, list) {
@@ -281,21 +292,23 @@ static int filter_add_pred_fn(struct ftrace_event_call *call,
			      struct filter_pred *pred,
			      struct filter_pred *pred,
			      filter_pred_fn_t fn)
			      filter_pred_fn_t fn)
{
{
	struct event_filter *filter = call->filter;
	int idx, err;
	int idx, err;


	if (call->n_preds && !pred->compound)
	if (filter->n_preds && !pred->compound)
		__filter_disable_preds(call);
		__filter_disable_preds(call);


	if (call->n_preds == MAX_FILTER_PRED)
	if (filter->n_preds == MAX_FILTER_PRED)
		return -ENOSPC;
		return -ENOSPC;


	idx = call->n_preds;
	idx = filter->n_preds;
	filter_clear_pred(call->preds[idx]);
	filter_clear_pred(filter->preds[idx]);
	err = filter_set_pred(call->preds[idx], pred, fn);
	err = filter_set_pred(filter->preds[idx], pred, fn);
	if (err)
	if (err)
		return err;
		return err;


	call->n_preds++;
	filter->n_preds++;
	call->filter_active = 1;


	return 0;
	return 0;
}
}
@@ -366,29 +379,41 @@ int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred)
int filter_add_subsystem_pred(struct event_subsystem *system,
int filter_add_subsystem_pred(struct event_subsystem *system,
			      struct filter_pred *pred)
			      struct filter_pred *pred)
{
{
	struct event_filter *filter = system->filter;
	struct ftrace_event_call *call;
	struct ftrace_event_call *call;


	mutex_lock(&filter_mutex);
	mutex_lock(&filter_mutex);


	if (system->n_preds && !pred->compound)
	if (filter && filter->n_preds && !pred->compound) {
		__filter_free_subsystem_preds(system);
		__filter_free_subsystem_preds(system);
		filter = NULL;
	}


	if (!system->n_preds) {
	if (!filter) {
		system->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
		system->filter = kzalloc(sizeof(*filter), GFP_KERNEL);
		if (!system->filter) {
			mutex_unlock(&filter_mutex);
			return -ENOMEM;
		}
		filter = system->filter;
		filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
					GFP_KERNEL);
					GFP_KERNEL);
		if (!system->preds) {

		if (!filter->preds) {
			kfree(system->filter);
			system->filter = NULL;
			mutex_unlock(&filter_mutex);
			mutex_unlock(&filter_mutex);
			return -ENOMEM;
			return -ENOMEM;
		}
		}
	}
	}


	if (system->n_preds == MAX_FILTER_PRED) {
	if (filter->n_preds == MAX_FILTER_PRED) {
		mutex_unlock(&filter_mutex);
		mutex_unlock(&filter_mutex);
		return -ENOSPC;
		return -ENOSPC;
	}
	}


	system->preds[system->n_preds] = pred;
	filter->preds[filter->n_preds] = pred;
	system->n_preds++;
	filter->n_preds++;


	list_for_each_entry(call, &ftrace_events, list) {
	list_for_each_entry(call, &ftrace_events, list) {
		int err;
		int err;
@@ -401,8 +426,8 @@ int filter_add_subsystem_pred(struct event_subsystem *system,


		err = __filter_add_pred(call, pred);
		err = __filter_add_pred(call, pred);
		if (err == -ENOMEM) {
		if (err == -ENOMEM) {
			system->preds[system->n_preds] = NULL;
			filter->preds[filter->n_preds] = NULL;
			system->n_preds--;
			filter->n_preds--;
			mutex_unlock(&filter_mutex);
			mutex_unlock(&filter_mutex);
			return err;
			return err;
		}
		}