Messages in this thread Patch in this message | | | Subject | [PATCH] tracing/filters: allow event filters to be set only when not tracing | From | Tom Zanussi <> | Date | Mon, 30 Mar 2009 00:22:26 -0500 |
| |
This patch adds code allowing the event filter to be set only if there's no active tracing going on.
Signed-off-by: Tom Zanussi <tzanussi@gmail.com>
--- kernel/trace/trace.c | 13 +++++++++++++ kernel/trace/trace.h | 2 ++ kernel/trace/trace_events.c | 7 +++++++ kernel/trace/trace_events_filter.c | 12 ++++++++++++ 4 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3624b25..30530f7 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -235,6 +235,19 @@ static struct tracer *trace_types __read_mostly; /* current_trace points to the tracer that is currently active */ static struct tracer *current_trace __read_mostly; +/** + * tracer_is_nop - return if nop tracer is current tracer + * + * This function is used by other tracers to know whether there is + * currently a tracer set. Tracers may use this function to know if + * it should enable their features when starting up. See event tracer + * for an example (event_filter_write). + */ +int tracer_is_nop(void) +{ + return current_trace == &nop_trace; +} + /* * max_tracer_type_len is used to simplify the allocating of * buffers to read userspace tracer names. We keep track of diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index cfb07ef..6834345 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -466,6 +466,7 @@ struct trace_iterator { int tracer_init(struct tracer *t, struct trace_array *tr); int tracing_is_enabled(void); +int tracer_is_nop(void); void trace_wake_up(void); void tracing_reset(struct trace_array *tr, int cpu); void tracing_reset_online_cpus(struct trace_array *tr); @@ -859,6 +860,7 @@ extern int filter_match_preds(struct ftrace_event_call *call, void *rec); extern void filter_free_subsystem_preds(struct event_subsystem *system); extern int filter_add_subsystem_pred(struct event_subsystem *system, struct filter_pred *pred); +extern int subsystem_events_enabled(struct event_subsystem *system); static inline void filter_check_discard(struct ftrace_event_call *call, void *rec, diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index be9299a..eb1d363 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -498,6 +498,9 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, struct filter_pred *pred; int err; + if (tracing_is_enabled() && (!tracer_is_nop() || call->enabled)) + return -EBUSY; + if (cnt >= sizeof(buf)) return -EINVAL; @@ -564,6 +567,10 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, struct filter_pred *pred; int err; + if (tracing_is_enabled() && + (!tracer_is_nop() || subsystem_events_enabled(system))) + return -EBUSY; + if (cnt >= sizeof(buf)) return -EINVAL; diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 470ad94..a706e0b 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -172,6 +172,18 @@ void filter_free_preds(struct ftrace_event_call *call) } } +int subsystem_events_enabled(struct event_subsystem *system) +{ + struct ftrace_event_call *call = __start_ftrace_events; + + events_for_each(call) { + if (!strcmp(call->system, system->name) && call->enabled) + return 1; + } + + return 0; +} + void filter_free_subsystem_preds(struct event_subsystem *system) { struct ftrace_event_call *call = __start_ftrace_events; -- 1.5.6.3
| |