Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 141010
b: refs/heads/master
c: 7ce7e42
h: refs/heads/master
v: v3
  • Loading branch information
Tom Zanussi authored and Ingo Molnar committed Mar 22, 2009
1 parent f4b3e20 commit 10e2847
Show file tree
Hide file tree
Showing 6 changed files with 437 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: 2d622719f1572ef31e0616444a515eba3094d050
refs/heads/master: 7ce7e4249921d5073e764f7ff7ad83cfa9894bd7
1 change: 1 addition & 0 deletions trunk/kernel/trace/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ obj-$(CONFIG_EVENT_TRACER) += events.o
obj-$(CONFIG_EVENT_TRACER) += trace_export.o
obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
obj-$(CONFIG_EVENT_TRACER) += trace_events_filter.o

libftrace-y := ftrace.o
28 changes: 28 additions & 0 deletions trunk/kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,7 @@ struct ftrace_event_call {
int (*show_format)(struct trace_seq *s);
int (*define_fields)(void);
struct list_head fields;
struct filter_pred **preds;

#ifdef CONFIG_EVENT_PROFILE
atomic_t profile_count;
Expand All @@ -803,8 +804,35 @@ struct ftrace_event_call {
#endif
};

#define MAX_FILTER_PRED 8

struct filter_pred;

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

struct filter_pred {
filter_pred_fn_t fn;
u64 val;
char *str_val;
int str_len;
char *field_name;
int offset;
int not;
int or;
int compound;
int clear;
};

int trace_define_field(struct ftrace_event_call *call, char *type,
char *name, int offset, int size);
extern void filter_free_pred(struct filter_pred *pred);
extern int filter_print_preds(struct filter_pred **preds, char *buf);
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_free_preds(struct ftrace_event_call *call);
extern int filter_match_preds(struct ftrace_event_call *call, void *rec);

void event_trace_printk(unsigned long ip, const char *fmt, ...);
extern struct ftrace_event_call __start_ftrace_events[];
extern struct ftrace_event_call __stop_ftrace_events[];
Expand Down
77 changes: 77 additions & 0 deletions trunk/kernel/trace/trace_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,71 @@ event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
return r;
}

static ssize_t
event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
loff_t *ppos)
{
struct ftrace_event_call *call = filp->private_data;
struct trace_seq *s;
int r;

if (*ppos)
return 0;

s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s)
return -ENOMEM;

trace_seq_init(s);

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

kfree(s);

return r;
}

static ssize_t
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;
int err;

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

if (copy_from_user(&buf, ubuf, cnt))
return -EFAULT;

pred = kzalloc(sizeof(*pred), GFP_KERNEL);
if (!pred)
return -ENOMEM;

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

if (pred->clear) {
filter_free_preds(call);
return cnt;
}

if (filter_add_pred(call, pred)) {
filter_free_pred(pred);
return -EINVAL;
}

*ppos += cnt;

return cnt;
}

static const struct seq_operations show_event_seq_ops = {
.start = t_start,
.next = t_next,
Expand Down Expand Up @@ -504,6 +569,12 @@ static const struct file_operations ftrace_event_id_fops = {
.read = event_id_read,
};

static const struct file_operations ftrace_event_filter_fops = {
.open = tracing_open_generic,
.read = event_filter_read,
.write = event_filter_write,
};

static struct dentry *event_trace_events_dir(void)
{
static struct dentry *d_tracer;
Expand Down Expand Up @@ -619,6 +690,12 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
}
}

entry = debugfs_create_file("filter", 0444, call->dir, call,
&ftrace_event_filter_fops);
if (!entry)
pr_warning("Could not create debugfs "
"'%s/filter' entry\n", call->name);

/* A trace may not want to export its format */
if (!call->show_format)
return 0;
Expand Down
Loading

0 comments on commit 10e2847

Please sign in to comment.