aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.h
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2009-03-22 04:31:04 -0400
committerIngo Molnar <mingo@elte.hu>2009-03-22 13:38:46 -0400
commit7ce7e4249921d5073e764f7ff7ad83cfa9894bd7 (patch)
treed8a3026e85d3230ce39ca99f446abe76a710c337 /kernel/trace/trace.h
parent2d622719f1572ef31e0616444a515eba3094d050 (diff)
tracing: add per-event filtering
This patch adds per-event filtering to the event tracing subsystem. It adds a 'filter' debugfs file to each event directory. This file can be written to to set filters; reading from it will display the current set of filters set for that event. Basically, any field listed in the 'format' file for an event can be filtered on (including strings, but not yet other array types) using either matching ('==') or non-matching ('!=') 'predicates'. A 'predicate' can be either a single expression: # echo pid != 0 > filter # cat filter pid != 0 or a compound expression of up to 8 sub-expressions combined using '&&' or '||': # echo comm == Xorg > filter # echo "&& sig != 29" > filter # cat filter comm == Xorg && sig != 29 Only events having field values matching an expression will be available in the trace output; non-matching events are discarded. Note that a compound expression is built up by echoing each sub-expression separately - it's not the most efficient way to do things, but it keeps the parser simple and assumes that compound expressions will be relatively uncommon. In any case, a subsequent patch introducing a way to set filters for entire subsystems should mitigate any need to do this for lots of events. Setting a filter without an '&&' or '||' clears the previous filter completely and sets the filter to the new expression: # cat filter comm == Xorg && sig != 29 # echo comm != Xorg # cat filter comm != Xorg To clear a filter, echo 0 to the filter file: # echo 0 > filter # cat filter none The limit of 8 predicates for a compound expression is arbitrary - for efficiency, it's implemented as an array of pointers to predicates, and 8 seemed more than enough for any filter... Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <1237710665.7703.48.camel@charm-linux> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/trace.h')
-rw-r--r--kernel/trace/trace.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 9288dc7ad14f..d9eb39e4bb38 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -795,6 +795,7 @@ struct ftrace_event_call {
795 int (*show_format)(struct trace_seq *s); 795 int (*show_format)(struct trace_seq *s);
796 int (*define_fields)(void); 796 int (*define_fields)(void);
797 struct list_head fields; 797 struct list_head fields;
798 struct filter_pred **preds;
798 799
799#ifdef CONFIG_EVENT_PROFILE 800#ifdef CONFIG_EVENT_PROFILE
800 atomic_t profile_count; 801 atomic_t profile_count;
@@ -803,8 +804,35 @@ struct ftrace_event_call {
803#endif 804#endif
804}; 805};
805 806
807#define MAX_FILTER_PRED 8
808
809struct filter_pred;
810
811typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event);
812
813struct filter_pred {
814 filter_pred_fn_t fn;
815 u64 val;
816 char *str_val;
817 int str_len;
818 char *field_name;
819 int offset;
820 int not;
821 int or;
822 int compound;
823 int clear;
824};
825
806int trace_define_field(struct ftrace_event_call *call, char *type, 826int trace_define_field(struct ftrace_event_call *call, char *type,
807 char *name, int offset, int size); 827 char *name, int offset, int size);
828extern void filter_free_pred(struct filter_pred *pred);
829extern int filter_print_preds(struct filter_pred **preds, char *buf);
830extern int filter_parse(char **pbuf, struct filter_pred *pred);
831extern int filter_add_pred(struct ftrace_event_call *call,
832 struct filter_pred *pred);
833extern void filter_free_preds(struct ftrace_event_call *call);
834extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
835
808void event_trace_printk(unsigned long ip, const char *fmt, ...); 836void event_trace_printk(unsigned long ip, const char *fmt, ...);
809extern struct ftrace_event_call __start_ftrace_events[]; 837extern struct ftrace_event_call __start_ftrace_events[];
810extern struct ftrace_event_call __stop_ftrace_events[]; 838extern struct ftrace_event_call __stop_ftrace_events[];