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

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
...@@ -101,8 +101,8 @@ struct ftrace_event_call { ...@@ -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
......
...@@ -731,12 +731,16 @@ struct ftrace_event_field { ...@@ -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, ...@@ -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;
} }
......
...@@ -757,8 +757,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events) ...@@ -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);
......
...@@ -93,11 +93,12 @@ static int filter_pred_none(struct filter_pred *pred, void *event) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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); ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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;
} }
......
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