Skip to content

Commit

Permalink
tracing: add protection around module events unload
Browse files Browse the repository at this point in the history
When reading the trace buffer, there is a race that when a module
is unloaded it removes events that is stilled referenced in the buffers.
This patch adds the protection around the unloading of the events
from modules and the reading of the trace buffers.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed Jun 9, 2009
1 parent 725c624 commit 110bf2b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
4 changes: 3 additions & 1 deletion kernel/trace/trace_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,12 +1050,13 @@ static void trace_module_remove_events(struct module *mod)
struct ftrace_event_call *call, *p;
bool found = false;

down_write(&trace_event_mutex);
list_for_each_entry_safe(call, p, &ftrace_events, list) {
if (call->mod == mod) {
found = true;
ftrace_event_enable_disable(call, 0);
if (call->event)
unregister_ftrace_event(call->event);
__unregister_ftrace_event(call->event);
debugfs_remove_recursive(call->dir);
list_del(&call->list);
trace_destroy_fields(call);
Expand All @@ -1079,6 +1080,7 @@ static void trace_module_remove_events(struct module *mod)
*/
if (found)
tracing_reset_current_online_cpus();
up_write(&trace_event_mutex);
}

static int trace_module_notify(struct notifier_block *self,
Expand Down
15 changes: 12 additions & 3 deletions kernel/trace/trace_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/* must be a power of 2 */
#define EVENT_HASHSIZE 128

static DECLARE_RWSEM(trace_event_mutex);
DECLARE_RWSEM(trace_event_mutex);

DEFINE_PER_CPU(struct trace_seq, ftrace_event_seq);
EXPORT_PER_CPU_SYMBOL(ftrace_event_seq);
Expand Down Expand Up @@ -702,15 +702,24 @@ int register_ftrace_event(struct trace_event *event)
}
EXPORT_SYMBOL_GPL(register_ftrace_event);

/*
* Used by module code with the trace_event_mutex held for write.
*/
int __unregister_ftrace_event(struct trace_event *event)
{
hlist_del(&event->node);
list_del(&event->list);
return 0;
}

/**
* unregister_ftrace_event - remove a no longer used event
* @event: the event to remove
*/
int unregister_ftrace_event(struct trace_event *event)
{
down_write(&trace_event_mutex);
hlist_del(&event->node);
list_del(&event->list);
__unregister_ftrace_event(event);
up_write(&trace_event_mutex);

return 0;
Expand Down
4 changes: 4 additions & 0 deletions kernel/trace/trace_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ extern struct trace_event *ftrace_find_event(int type);
extern enum print_line_t trace_nop_print(struct trace_iterator *iter,
int flags);

/* used by module unregistering */
extern int __unregister_ftrace_event(struct trace_event *event);
extern struct rw_semaphore trace_event_mutex;

#define MAX_MEMHEX_BYTES 8
#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)

Expand Down

0 comments on commit 110bf2b

Please sign in to comment.