Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 146075
b: refs/heads/master
c: 8b37256
h: refs/heads/master
i:
  146073: 63a8631
  146071: 4f5f109
v: v3
  • Loading branch information
Tom Zanussi authored and Ingo Molnar committed Apr 29, 2009
1 parent 7db551d commit 37491e4
Show file tree
Hide file tree
Showing 5 changed files with 885 additions and 291 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: a118e4d1402f1349fe3d953493e4168a300a752d
refs/heads/master: 8b3725621074040d380664964ffbc40610aef8c6
2 changes: 1 addition & 1 deletion trunk/include/linux/ftrace_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ struct ftrace_event_call {
#endif
};

#define MAX_FILTER_PRED 8
#define MAX_FILTER_PRED 32
#define MAX_FILTER_STR_VAL 128

extern int init_preds(struct ftrace_event_call *call);
Expand Down
66 changes: 52 additions & 14 deletions trunk/kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ struct ftrace_event_field {
struct event_filter {
int n_preds;
struct filter_pred **preds;
char *filter_string;
};

struct event_subsystem {
Expand All @@ -746,7 +747,8 @@ struct event_subsystem {

struct filter_pred;

typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event);
typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event,
int val1, int val2);

struct filter_pred {
filter_pred_fn_t fn;
Expand All @@ -756,23 +758,18 @@ struct filter_pred {
char *field_name;
int offset;
int not;
int or;
int compound;
int clear;
int op;
int pop_n;
};

extern void filter_free_pred(struct filter_pred *pred);
extern void filter_print_preds(struct ftrace_event_call *call,
extern void print_event_filter(struct ftrace_event_call *call,
struct trace_seq *s);
extern int filter_parse(char **pbuf, struct filter_pred *pred);
extern int filter_add_pred(struct ftrace_event_call *call,
struct filter_pred *pred);
extern void filter_disable_preds(struct ftrace_event_call *call);
extern void filter_free_subsystem_preds(struct event_subsystem *system);
extern void filter_print_subsystem_preds(struct event_subsystem *system,
extern int apply_event_filter(struct ftrace_event_call *call,
char *filter_string);
extern int apply_subsystem_event_filter(struct event_subsystem *system,
char *filter_string);
extern void print_subsystem_event_filter(struct event_subsystem *system,
struct trace_seq *s);
extern int filter_add_subsystem_pred(struct event_subsystem *system,
struct filter_pred *pred);

static inline int
filter_check_discard(struct ftrace_event_call *call, void *rec,
Expand All @@ -787,6 +784,47 @@ filter_check_discard(struct ftrace_event_call *call, void *rec,
return 0;
}

#define DEFINE_COMPARISON_PRED(type) \
static int filter_pred_##type(struct filter_pred *pred, void *event, \
int val1, int val2) \
{ \
type *addr = (type *)(event + pred->offset); \
type val = (type)pred->val; \
int match = 0; \
\
switch (pred->op) { \
case OP_LT: \
match = (*addr < val); \
break; \
case OP_LE: \
match = (*addr <= val); \
break; \
case OP_GT: \
match = (*addr > val); \
break; \
case OP_GE: \
match = (*addr >= val); \
break; \
default: \
break; \
} \
\
return match; \
}

#define DEFINE_EQUALITY_PRED(size) \
static int filter_pred_##size(struct filter_pred *pred, void *event, \
int val1, int val2) \
{ \
u##size *addr = (u##size *)(event + pred->offset); \
u##size val = (u##size)pred->val; \
int match; \
\
match = (val == *addr) ^ pred->not; \
\
return match; \
}

extern struct list_head ftrace_events;

extern const char *__start___trace_bprintk_fmt[];
Expand Down
86 changes: 35 additions & 51 deletions trunk/kernel/trace/trace_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,

trace_seq_init(s);

filter_print_preds(call, s);
print_event_filter(call, s);
r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);

kfree(s);
Expand All @@ -505,40 +505,26 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
loff_t *ppos)
{
struct ftrace_event_call *call = filp->private_data;
char buf[64], *pbuf = buf;
struct filter_pred *pred;
char *buf;
int err;

if (cnt >= sizeof(buf))
if (cnt >= PAGE_SIZE)
return -EINVAL;

if (copy_from_user(&buf, ubuf, cnt))
return -EFAULT;
buf[cnt] = '\0';

pred = kzalloc(sizeof(*pred), GFP_KERNEL);
if (!pred)
buf = (char *)__get_free_page(GFP_TEMPORARY);
if (!buf)
return -ENOMEM;

err = filter_parse(&pbuf, pred);
if (err < 0) {
filter_free_pred(pred);
return err;
}

if (pred->clear) {
filter_disable_preds(call);
filter_free_pred(pred);
return cnt;
if (copy_from_user(buf, ubuf, cnt)) {
free_page((unsigned long) buf);
return -EFAULT;
}
buf[cnt] = '\0';

err = filter_add_pred(call, pred);
if (err < 0) {
filter_free_pred(pred);
err = apply_event_filter(call, buf);
free_page((unsigned long) buf);
if (err < 0)
return err;
}

filter_free_pred(pred);

*ppos += cnt;

Expand All @@ -562,7 +548,7 @@ subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,

trace_seq_init(s);

filter_print_subsystem_preds(system, s);
print_subsystem_event_filter(system, s);
r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);

kfree(s);
Expand All @@ -575,38 +561,26 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
loff_t *ppos)
{
struct event_subsystem *system = filp->private_data;
char buf[64], *pbuf = buf;
struct filter_pred *pred;
char *buf;
int err;

if (cnt >= sizeof(buf))
if (cnt >= PAGE_SIZE)
return -EINVAL;

if (copy_from_user(&buf, ubuf, cnt))
return -EFAULT;
buf[cnt] = '\0';

pred = kzalloc(sizeof(*pred), GFP_KERNEL);
if (!pred)
buf = (char *)__get_free_page(GFP_TEMPORARY);
if (!buf)
return -ENOMEM;

err = filter_parse(&pbuf, pred);
if (err < 0) {
filter_free_pred(pred);
return err;
}

if (pred->clear) {
filter_free_subsystem_preds(system);
filter_free_pred(pred);
return cnt;
if (copy_from_user(buf, ubuf, cnt)) {
free_page((unsigned long) buf);
return -EFAULT;
}
buf[cnt] = '\0';

err = filter_add_subsystem_pred(system, pred);
if (err < 0) {
filter_free_pred(pred);
err = apply_subsystem_event_filter(system, buf);
free_page((unsigned long) buf);
if (err < 0)
return err;
}

*ppos += cnt;

Expand Down Expand Up @@ -760,11 +734,21 @@ event_subsystem_dir(const char *name, struct dentry *d_events)

system->filter = NULL;

system->filter = kzalloc(sizeof(struct event_filter), GFP_KERNEL);
if (!system->filter) {
pr_warning("Could not allocate filter for subsystem "
"'%s'\n", name);
return system->entry;
}

entry = debugfs_create_file("filter", 0644, system->entry, system,
&ftrace_subsystem_filter_fops);
if (!entry)
if (!entry) {
kfree(system->filter);
system->filter = NULL;
pr_warning("Could not create debugfs "
"'%s/filter' entry\n", name);
}

return system->entry;
}
Expand Down
Loading

0 comments on commit 37491e4

Please sign in to comment.