diff options
author | Oleg Nesterov <oleg@redhat.com> | 2013-07-29 13:50:33 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-29 12:47:34 -0400 |
commit | 8169887b694aa3d9632fdd0308aaa1db7c422e75 (patch) | |
tree | 521d15d1f21cdcbbf25d490a3a0f850e31635fbe /include | |
parent | 012dc156d6af49e02a30fcba7d688e251608d97c (diff) |
tracing: trace_remove_event_call() should fail if call/file is in use
commit 2816c551c796ec14620325b2c9ed75b9979d3125 upstream.
Change trace_remove_event_call(call) to return the error if this
call is active. This is what the callers assume but can't verify
outside of the tracing locks. Both trace_kprobe.c/trace_uprobe.c
need the additional changes, unregister_trace_probe() should abort
if trace_remove_event_call() fails.
The caller is going to free this call/file so we must ensure that
nobody can use them after trace_remove_event_call() succeeds.
debugfs should be fine after the previous changes and event_remove()
does TRACE_REG_UNREGISTER, but still there are 2 reasons why we need
the additional checks:
- There could be a perf_event(s) attached to this tp_event, so the
patch checks ->perf_refcount.
- TRACE_REG_UNREGISTER can be suppressed by FTRACE_EVENT_FL_SOFT_MODE,
so we simply check FTRACE_EVENT_FL_ENABLED protected by event_mutex.
Link: http://lkml.kernel.org/r/20130729175033.GB26284@redhat.com
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/ftrace_event.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 44cdc11b15c2..120d57a1c3a5 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -334,7 +334,7 @@ extern int trace_define_field(struct ftrace_event_call *call, const char *type, | |||
334 | const char *name, int offset, int size, | 334 | const char *name, int offset, int size, |
335 | int is_signed, int filter_type); | 335 | int is_signed, int filter_type); |
336 | extern int trace_add_event_call(struct ftrace_event_call *call); | 336 | extern int trace_add_event_call(struct ftrace_event_call *call); |
337 | extern void trace_remove_event_call(struct ftrace_event_call *call); | 337 | extern int trace_remove_event_call(struct ftrace_event_call *call); |
338 | 338 | ||
339 | #define is_signed_type(type) (((type)(-1)) < (type)1) | 339 | #define is_signed_type(type) (((type)(-1)) < (type)1) |
340 | 340 | ||