Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 285071
b: refs/heads/master
c: 38b78eb
h: refs/heads/master
i:
  285069: 86d3217
  285067: a4c00fe
  285063: ee47664
  285055: cb71898
v: v3
  • Loading branch information
Tejun Heo authored and Steven Rostedt committed Dec 21, 2011
1 parent 93a684a commit 91eb3bd
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 142 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 762e1207889b3451c50d365b741af6f9ce958886
refs/heads/master: 38b78eb855409a05f9d370228bec1955e6878e08
283 changes: 142 additions & 141 deletions trunk/kernel/trace/trace_events_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1738,11 +1738,121 @@ static int replace_system_preds(struct event_subsystem *system,
return -ENOMEM;
}

static int create_filter_start(char *filter_str, bool set_str,
struct filter_parse_state **psp,
struct event_filter **filterp)
{
struct event_filter *filter;
struct filter_parse_state *ps = NULL;
int err = 0;

WARN_ON_ONCE(*psp || *filterp);

/* allocate everything, and if any fails, free all and fail */
filter = __alloc_filter();
if (filter && set_str)
err = replace_filter_string(filter, filter_str);

ps = kzalloc(sizeof(*ps), GFP_KERNEL);

if (!filter || !ps || err) {
kfree(ps);
__free_filter(filter);
return -ENOMEM;
}

/* we're committed to creating a new filter */
*filterp = filter;
*psp = ps;

parse_init(ps, filter_ops, filter_str);
err = filter_parse(ps);
if (err && set_str)
append_filter_err(ps, filter);
return err;
}

static void create_filter_finish(struct filter_parse_state *ps)
{
if (ps) {
filter_opstack_clear(ps);
postfix_clear(ps);
kfree(ps);
}
}

/**
* create_filter - create a filter for a ftrace_event_call
* @call: ftrace_event_call to create a filter for
* @filter_str: filter string
* @set_str: remember @filter_str and enable detailed error in filter
* @filterp: out param for created filter (always updated on return)
*
* Creates a filter for @call with @filter_str. If @set_str is %true,
* @filter_str is copied and recorded in the new filter.
*
* On success, returns 0 and *@filterp points to the new filter. On
* failure, returns -errno and *@filterp may point to %NULL or to a new
* filter. In the latter case, the returned filter contains error
* information if @set_str is %true and the caller is responsible for
* freeing it.
*/
static int create_filter(struct ftrace_event_call *call,
char *filter_str, bool set_str,
struct event_filter **filterp)
{
struct event_filter *filter = NULL;
struct filter_parse_state *ps = NULL;
int err;

err = create_filter_start(filter_str, set_str, &ps, &filter);
if (!err) {
err = replace_preds(call, filter, ps, filter_str, false);
if (err && set_str)
append_filter_err(ps, filter);
}
create_filter_finish(ps);

*filterp = filter;
return err;
}

/**
* create_system_filter - create a filter for an event_subsystem
* @system: event_subsystem to create a filter for
* @filter_str: filter string
* @filterp: out param for created filter (always updated on return)
*
* Identical to create_filter() except that it creates a subsystem filter
* and always remembers @filter_str.
*/
static int create_system_filter(struct event_subsystem *system,
char *filter_str, struct event_filter **filterp)
{
struct event_filter *filter = NULL;
struct filter_parse_state *ps = NULL;
int err;

err = create_filter_start(filter_str, true, &ps, &filter);
if (!err) {
err = replace_system_preds(system, ps, filter_str);
if (!err) {
/* System filters just show a default message */
kfree(filter->filter_string);
filter->filter_string = NULL;
} else {
append_filter_err(ps, filter);
}
}
create_filter_finish(ps);

*filterp = filter;
return err;
}

int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
{
struct filter_parse_state *ps;
struct event_filter *filter;
struct event_filter *tmp;
int err = 0;

mutex_lock(&event_mutex);
Expand All @@ -1759,49 +1869,30 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
goto out_unlock;
}

err = -ENOMEM;
ps = kzalloc(sizeof(*ps), GFP_KERNEL);
if (!ps)
goto out_unlock;

filter = __alloc_filter();
if (!filter) {
kfree(ps);
goto out_unlock;
}

replace_filter_string(filter, filter_string);

parse_init(ps, filter_ops, filter_string);
err = filter_parse(ps);
if (err) {
append_filter_err(ps, filter);
goto out;
}
err = create_filter(call, filter_string, true, &filter);

err = replace_preds(call, filter, ps, filter_string, false);
if (err) {
filter_disable(call);
append_filter_err(ps, filter);
} else
call->flags |= TRACE_EVENT_FL_FILTERED;
out:
/*
* Always swap the call filter with the new filter
* even if there was an error. If there was an error
* in the filter, we disable the filter and show the error
* string
*/
tmp = call->filter;
rcu_assign_pointer(call->filter, filter);
if (tmp) {
/* Make sure the call is done with the filter */
synchronize_sched();
__free_filter(tmp);
if (filter) {
struct event_filter *tmp = call->filter;

if (!err)
call->flags |= TRACE_EVENT_FL_FILTERED;
else
filter_disable(call);

rcu_assign_pointer(call->filter, filter);

if (tmp) {
/* Make sure the call is done with the filter */
synchronize_sched();
__free_filter(tmp);
}
}
filter_opstack_clear(ps);
postfix_clear(ps);
kfree(ps);
out_unlock:
mutex_unlock(&event_mutex);

Expand All @@ -1811,7 +1902,6 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
int apply_subsystem_event_filter(struct event_subsystem *system,
char *filter_string)
{
struct filter_parse_state *ps;
struct event_filter *filter;
int err = 0;

Expand All @@ -1835,48 +1925,19 @@ int apply_subsystem_event_filter(struct event_subsystem *system,
goto out_unlock;
}

err = -ENOMEM;
ps = kzalloc(sizeof(*ps), GFP_KERNEL);
if (!ps)
goto out_unlock;

filter = __alloc_filter();
if (!filter)
goto out;

/* System filters just show a default message */
kfree(filter->filter_string);
filter->filter_string = NULL;

/*
* No event actually uses the system filter
* we can free it without synchronize_sched().
*/
__free_filter(system->filter);
system->filter = filter;

parse_init(ps, filter_ops, filter_string);
err = filter_parse(ps);
if (err)
goto err_filter;

err = replace_system_preds(system, ps, filter_string);
if (err)
goto err_filter;

out:
filter_opstack_clear(ps);
postfix_clear(ps);
kfree(ps);
err = create_system_filter(system, filter_string, &filter);
if (filter) {
/*
* No event actually uses the system filter
* we can free it without synchronize_sched().
*/
__free_filter(system->filter);
system->filter = filter;
}
out_unlock:
mutex_unlock(&event_mutex);

return err;

err_filter:
replace_filter_string(filter, filter_string);
append_filter_err(ps, system->filter);
goto out;
}

#ifdef CONFIG_PERF_EVENTS
Expand All @@ -1894,7 +1955,6 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
{
int err;
struct event_filter *filter;
struct filter_parse_state *ps;
struct ftrace_event_call *call;

mutex_lock(&event_mutex);
Expand All @@ -1909,33 +1969,10 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
if (event->filter)
goto out_unlock;

filter = __alloc_filter();
if (!filter) {
err = PTR_ERR(filter);
goto out_unlock;
}

err = -ENOMEM;
ps = kzalloc(sizeof(*ps), GFP_KERNEL);
if (!ps)
goto free_filter;

parse_init(ps, filter_ops, filter_str);
err = filter_parse(ps);
if (err)
goto free_ps;

err = replace_preds(call, filter, ps, filter_str, false);
err = create_filter(call, filter_str, false, &filter);
if (!err)
event->filter = filter;

free_ps:
filter_opstack_clear(ps);
postfix_clear(ps);
kfree(ps);

free_filter:
if (err)
else
__free_filter(filter);

out_unlock:
Expand All @@ -1954,43 +1991,6 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
#define CREATE_TRACE_POINTS
#include "trace_events_filter_test.h"

static int test_get_filter(char *filter_str, struct ftrace_event_call *call,
struct event_filter **pfilter)
{
struct event_filter *filter;
struct filter_parse_state *ps;
int err = -ENOMEM;

filter = __alloc_filter();
if (!filter)
goto out;

ps = kzalloc(sizeof(*ps), GFP_KERNEL);
if (!ps)
goto free_filter;

parse_init(ps, filter_ops, filter_str);
err = filter_parse(ps);
if (err)
goto free_ps;

err = replace_preds(call, filter, ps, filter_str, false);
if (!err)
*pfilter = filter;

free_ps:
filter_opstack_clear(ps);
postfix_clear(ps);
kfree(ps);

free_filter:
if (err)
__free_filter(filter);

out:
return err;
}

#define DATA_REC(m, va, vb, vc, vd, ve, vf, vg, vh, nvisit) \
{ \
.filter = FILTER, \
Expand Down Expand Up @@ -2109,12 +2109,13 @@ static __init int ftrace_test_event_filter(void)
struct test_filter_data_t *d = &test_filter_data[i];
int err;

err = test_get_filter(d->filter, &event_ftrace_test_filter,
&filter);
err = create_filter(&event_ftrace_test_filter, d->filter,
false, &filter);
if (err) {
printk(KERN_INFO
"Failed to get filter for '%s', err %d\n",
d->filter, err);
__free_filter(filter);
break;
}

Expand Down

0 comments on commit 91eb3bd

Please sign in to comment.