aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_events.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_events.c')
-rw-r--r--kernel/trace/trace_events.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 961b057da28b..97470c48956e 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -459,6 +459,71 @@ event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
459 return r; 459 return r;
460} 460}
461 461
462static ssize_t
463event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
464 loff_t *ppos)
465{
466 struct ftrace_event_call *call = filp->private_data;
467 struct trace_seq *s;
468 int r;
469
470 if (*ppos)
471 return 0;
472
473 s = kmalloc(sizeof(*s), GFP_KERNEL);
474 if (!s)
475 return -ENOMEM;
476
477 trace_seq_init(s);
478
479 r = filter_print_preds(call->preds, s->buffer);
480 r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, r);
481
482 kfree(s);
483
484 return r;
485}
486
487static ssize_t
488event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
489 loff_t *ppos)
490{
491 struct ftrace_event_call *call = filp->private_data;
492 char buf[64], *pbuf = buf;
493 struct filter_pred *pred;
494 int err;
495
496 if (cnt >= sizeof(buf))
497 return -EINVAL;
498
499 if (copy_from_user(&buf, ubuf, cnt))
500 return -EFAULT;
501
502 pred = kzalloc(sizeof(*pred), GFP_KERNEL);
503 if (!pred)
504 return -ENOMEM;
505
506 err = filter_parse(&pbuf, pred);
507 if (err < 0) {
508 filter_free_pred(pred);
509 return err;
510 }
511
512 if (pred->clear) {
513 filter_free_preds(call);
514 return cnt;
515 }
516
517 if (filter_add_pred(call, pred)) {
518 filter_free_pred(pred);
519 return -EINVAL;
520 }
521
522 *ppos += cnt;
523
524 return cnt;
525}
526
462static const struct seq_operations show_event_seq_ops = { 527static const struct seq_operations show_event_seq_ops = {
463 .start = t_start, 528 .start = t_start,
464 .next = t_next, 529 .next = t_next,
@@ -504,6 +569,12 @@ static const struct file_operations ftrace_event_id_fops = {
504 .read = event_id_read, 569 .read = event_id_read,
505}; 570};
506 571
572static const struct file_operations ftrace_event_filter_fops = {
573 .open = tracing_open_generic,
574 .read = event_filter_read,
575 .write = event_filter_write,
576};
577
507static struct dentry *event_trace_events_dir(void) 578static struct dentry *event_trace_events_dir(void)
508{ 579{
509 static struct dentry *d_tracer; 580 static struct dentry *d_tracer;
@@ -619,6 +690,12 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
619 } 690 }
620 } 691 }
621 692
693 entry = debugfs_create_file("filter", 0444, call->dir, call,
694 &ftrace_event_filter_fops);
695 if (!entry)
696 pr_warning("Could not create debugfs "
697 "'%s/filter' entry\n", call->name);
698
622 /* A trace may not want to export its format */ 699 /* A trace may not want to export its format */
623 if (!call->show_format) 700 if (!call->show_format)
624 return 0; 701 return 0;