Skip to content

Commit

Permalink
tracing/filter: Allocate the preds in an array
Browse files Browse the repository at this point in the history
Currently we allocate an array of pointers to filter_preds, and then
allocate a separate filter_pred for each item in the array.
This adds slight overhead in the filters as it needs to derefernce
twice to get to the op condition.

Allocating the preds themselves in a single array removes a dereference
as well as helps on the cache footprint.

Cc: Tom Zanussi <tzanussi@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed Feb 8, 2011
1 parent 0fc3ca9 commit 74e9e58
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 23 deletions.
2 changes: 1 addition & 1 deletion kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ struct ftrace_event_field {
struct event_filter {
int n_preds; /* Number assigned */
int a_preds; /* allocated */
struct filter_pred **preds;
struct filter_pred *preds;
char *filter_string;
};

Expand Down
31 changes: 9 additions & 22 deletions kernel/trace/trace_events_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ int filter_match_preds(struct event_filter *filter, void *rec)
{
int match = -1, top = 0, val1 = 0, val2 = 0;
int stack[MAX_FILTER_PRED];
struct filter_pred **preds;
struct filter_pred *preds;
struct filter_pred *pred;
int n_preds = ACCESS_ONCE(filter->n_preds);
int i;
Expand All @@ -377,7 +377,7 @@ int filter_match_preds(struct event_filter *filter, void *rec)
preds = rcu_dereference_sched(filter->preds);

for (i = 0; i < n_preds; i++) {
pred = preds[i];
pred = &preds[i];
if (!pred->pop_n) {
match = pred->fn(pred, rec);
stack[top++] = match;
Expand Down Expand Up @@ -559,10 +559,8 @@ static void __free_preds(struct event_filter *filter)
int i;

if (filter->preds) {
for (i = 0; i < filter->a_preds; i++) {
if (filter->preds[i])
filter_free_pred(filter->preds[i]);
}
for (i = 0; i < filter->a_preds; i++)
kfree(filter->preds[i].field_name);
kfree(filter->preds);
filter->preds = NULL;
}
Expand All @@ -572,18 +570,15 @@ static void __free_preds(struct event_filter *filter)

static void reset_preds(struct event_filter *filter)
{
struct filter_pred *pred;
int n_preds = filter->n_preds;
int i;

filter->n_preds = 0;
if (!filter->preds)
return;

for (i = 0; i < n_preds; i++) {
pred = filter->preds[i];
pred->fn = filter_pred_none;
}
for (i = 0; i < n_preds; i++)
filter->preds[i].fn = filter_pred_none;
}

static void filter_disable_preds(struct ftrace_event_call *call)
Expand Down Expand Up @@ -658,19 +653,11 @@ static int __alloc_preds(struct event_filter *filter, int n_preds)
return -EINVAL;

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

return 0;
oom:
__free_preds(filter);
return -ENOMEM;
}

static int init_filter(struct ftrace_event_call *call)
Expand Down Expand Up @@ -730,8 +717,8 @@ static int filter_add_pred_fn(struct filter_parse_state *ps,
}

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

Expand Down

0 comments on commit 74e9e58

Please sign in to comment.