Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 269073
b: refs/heads/master
c: 1d0e78e
h: refs/heads/master
i:
  269071: 4d93091
v: v3
  • Loading branch information
Jiri Olsa authored and Steven Rostedt committed Aug 19, 2011
1 parent d336f72 commit 21ec2a7
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f30120fce1efaa426f340a354d5ace36dab59f0e
refs/heads/master: 1d0e78e380cd2802aa603a50e08220dfc681141c
2 changes: 2 additions & 0 deletions trunk/kernel/trace/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ ifdef CONFIG_TRACING_BRANCHES
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
endif

CFLAGS_trace_events_filter.o := -I$(src)

#
# Make the trace clocks available generally: it's infrastructure
# relied on by ptrace for example:
Expand Down
3 changes: 3 additions & 0 deletions trunk/kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,9 @@ struct filter_pred {
u64 val;
struct regex regex;
unsigned short *ops;
#ifdef CONFIG_FTRACE_STARTUP_TEST
struct ftrace_event_field *field;
#endif
int offset;
int not;
int op;
Expand Down
209 changes: 209 additions & 0 deletions trunk/kernel/trace/trace_events_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,9 @@ static struct filter_pred *create_pred(struct filter_parse_state *ps,
strcpy(pred.regex.pattern, operand2);
pred.regex.len = strlen(pred.regex.pattern);

#ifdef CONFIG_FTRACE_STARTUP_TEST
pred.field = field;
#endif
return init_pred(ps, field, &pred) ? NULL : &pred;
}

Expand Down Expand Up @@ -1926,3 +1929,209 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,

#endif /* CONFIG_PERF_EVENTS */

#ifdef CONFIG_FTRACE_STARTUP_TEST

#include <linux/types.h>
#include <linux/tracepoint.h>

#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, \
.rec = { .a = va, .b = vb, .c = vc, .d = vd, \
.e = ve, .f = vf, .g = vg, .h = vh }, \
.match = m, \
.not_visited = nvisit, \
}
#define YES 1
#define NO 0

static struct test_filter_data_t {
char *filter;
struct ftrace_raw_ftrace_test_filter rec;
int match;
char *not_visited;
} test_filter_data[] = {
#define FILTER "a == 1 && b == 1 && c == 1 && d == 1 && " \
"e == 1 && f == 1 && g == 1 && h == 1"
DATA_REC(YES, 1, 1, 1, 1, 1, 1, 1, 1, ""),
DATA_REC(NO, 0, 1, 1, 1, 1, 1, 1, 1, "bcdefgh"),
DATA_REC(NO, 1, 1, 1, 1, 1, 1, 1, 0, ""),
#undef FILTER
#define FILTER "a == 1 || b == 1 || c == 1 || d == 1 || " \
"e == 1 || f == 1 || g == 1 || h == 1"
DATA_REC(NO, 0, 0, 0, 0, 0, 0, 0, 0, ""),
DATA_REC(YES, 0, 0, 0, 0, 0, 0, 0, 1, ""),
DATA_REC(YES, 1, 0, 0, 0, 0, 0, 0, 0, "bcdefgh"),
#undef FILTER
#define FILTER "(a == 1 || b == 1) && (c == 1 || d == 1) && " \
"(e == 1 || f == 1) && (g == 1 || h == 1)"
DATA_REC(NO, 0, 0, 1, 1, 1, 1, 1, 1, "dfh"),
DATA_REC(YES, 0, 1, 0, 1, 0, 1, 0, 1, ""),
DATA_REC(YES, 1, 0, 1, 0, 0, 1, 0, 1, "bd"),
DATA_REC(NO, 1, 0, 1, 0, 0, 1, 0, 0, "bd"),
#undef FILTER
#define FILTER "(a == 1 && b == 1) || (c == 1 && d == 1) || " \
"(e == 1 && f == 1) || (g == 1 && h == 1)"
DATA_REC(YES, 1, 0, 1, 1, 1, 1, 1, 1, "efgh"),
DATA_REC(YES, 0, 0, 0, 0, 0, 0, 1, 1, ""),
DATA_REC(NO, 0, 0, 0, 0, 0, 0, 0, 1, ""),
#undef FILTER
#define FILTER "(a == 1 && b == 1) && (c == 1 && d == 1) && " \
"(e == 1 && f == 1) || (g == 1 && h == 1)"
DATA_REC(YES, 1, 1, 1, 1, 1, 1, 0, 0, "gh"),
DATA_REC(NO, 0, 0, 0, 0, 0, 0, 0, 1, ""),
DATA_REC(YES, 1, 1, 1, 1, 1, 0, 1, 1, ""),
#undef FILTER
#define FILTER "((a == 1 || b == 1) || (c == 1 || d == 1) || " \
"(e == 1 || f == 1)) && (g == 1 || h == 1)"
DATA_REC(YES, 1, 1, 1, 1, 1, 1, 0, 1, "bcdef"),
DATA_REC(NO, 0, 0, 0, 0, 0, 0, 0, 0, ""),
DATA_REC(YES, 1, 1, 1, 1, 1, 0, 1, 1, "h"),
#undef FILTER
#define FILTER "((((((((a == 1) && (b == 1)) || (c == 1)) && (d == 1)) || " \
"(e == 1)) && (f == 1)) || (g == 1)) && (h == 1))"
DATA_REC(YES, 1, 1, 1, 1, 1, 1, 1, 1, "ceg"),
DATA_REC(NO, 0, 1, 0, 1, 0, 1, 0, 1, ""),
DATA_REC(NO, 1, 0, 1, 0, 1, 0, 1, 0, ""),
#undef FILTER
#define FILTER "((((((((a == 1) || (b == 1)) && (c == 1)) || (d == 1)) && " \
"(e == 1)) || (f == 1)) && (g == 1)) || (h == 1))"
DATA_REC(YES, 1, 1, 1, 1, 1, 1, 1, 1, "bdfh"),
DATA_REC(YES, 0, 1, 0, 1, 0, 1, 0, 1, ""),
DATA_REC(YES, 1, 0, 1, 0, 1, 0, 1, 0, "bdfh"),
};

#undef DATA_REC
#undef FILTER
#undef YES
#undef NO

#define DATA_CNT (sizeof(test_filter_data)/sizeof(struct test_filter_data_t))

static int test_pred_visited;

static int test_pred_visited_fn(struct filter_pred *pred, void *event)
{
struct ftrace_event_field *field = pred->field;

test_pred_visited = 1;
printk(KERN_INFO "\npred visited %s\n", field->name);
return 1;
}

static int test_walk_pred_cb(enum move_type move, struct filter_pred *pred,
int *err, void *data)
{
char *fields = data;

if ((move == MOVE_DOWN) &&
(pred->left == FILTER_PRED_INVALID)) {
struct ftrace_event_field *field = pred->field;

if (!field) {
WARN(1, "all leafs should have field defined");
return WALK_PRED_DEFAULT;
}
if (!strchr(fields, *field->name))
return WALK_PRED_DEFAULT;

WARN_ON(!pred->fn);
pred->fn = test_pred_visited_fn;
}
return WALK_PRED_DEFAULT;
}

static __init int ftrace_test_event_filter(void)
{
int i;

printk(KERN_INFO "Testing ftrace filter: ");

for (i = 0; i < DATA_CNT; i++) {
struct event_filter *filter = NULL;
struct test_filter_data_t *d = &test_filter_data[i];
int err;

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

if (*d->not_visited)
walk_pred_tree(filter->preds, filter->root,
test_walk_pred_cb,
d->not_visited);

test_pred_visited = 0;
err = filter_match_preds(filter, &d->rec);

__free_filter(filter);

if (test_pred_visited) {
printk(KERN_INFO
"Failed, unwanted pred visited for filter %s\n",
d->filter);
break;
}

if (err != d->match) {
printk(KERN_INFO
"Failed to match filter '%s', expected %d\n",
d->filter, d->match);
break;
}
}

if (i == DATA_CNT)
printk(KERN_CONT "OK\n");

return 0;
}

late_initcall(ftrace_test_event_filter);

#endif /* CONFIG_FTRACE_STARTUP_TEST */
50 changes: 50 additions & 0 deletions trunk/kernel/trace/trace_events_filter_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM test

#if !defined(_TRACE_TEST_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_TEST_H

#include <linux/tracepoint.h>

TRACE_EVENT(ftrace_test_filter,

TP_PROTO(int a, int b, int c, int d, int e, int f, int g, int h),

TP_ARGS(a, b, c, d, e, f, g, h),

TP_STRUCT__entry(
__field(int, a)
__field(int, b)
__field(int, c)
__field(int, d)
__field(int, e)
__field(int, f)
__field(int, g)
__field(int, h)
),

TP_fast_assign(
__entry->a = a;
__entry->b = b;
__entry->c = c;
__entry->d = d;
__entry->e = e;
__entry->f = f;
__entry->g = g;
__entry->h = h;
),

TP_printk("a %d, b %d, c %d, d %d, e %d, f %d, g %d, h %d",
__entry->a, __entry->b, __entry->c, __entry->d,
__entry->e, __entry->f, __entry->g, __entry->h)
);

#endif /* _TRACE_TEST_H || TRACE_HEADER_MULTI_READ */

#undef TRACE_INCLUDE_PATH
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE trace_events_filter_test

/* This part must be outside protection */
#include <trace/define_trace.h>

0 comments on commit 21ec2a7

Please sign in to comment.