Skip to content

Commit 110bf2b

Browse files
Steven Rostedtrostedt
authored andcommitted
tracing: add protection around module events unload
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 <[email protected]>
1 parent 725c624 commit 110bf2b

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

kernel/trace/trace_events.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,12 +1050,13 @@ static void trace_module_remove_events(struct module *mod)
10501050
struct ftrace_event_call *call, *p;
10511051
bool found = false;
10521052

1053+
down_write(&trace_event_mutex);
10531054
list_for_each_entry_safe(call, p, &ftrace_events, list) {
10541055
if (call->mod == mod) {
10551056
found = true;
10561057
ftrace_event_enable_disable(call, 0);
10571058
if (call->event)
1058-
unregister_ftrace_event(call->event);
1059+
__unregister_ftrace_event(call->event);
10591060
debugfs_remove_recursive(call->dir);
10601061
list_del(&call->list);
10611062
trace_destroy_fields(call);
@@ -1079,6 +1080,7 @@ static void trace_module_remove_events(struct module *mod)
10791080
*/
10801081
if (found)
10811082
tracing_reset_current_online_cpus();
1083+
up_write(&trace_event_mutex);
10821084
}
10831085

10841086
static int trace_module_notify(struct notifier_block *self,

kernel/trace/trace_output.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/* must be a power of 2 */
1515
#define EVENT_HASHSIZE 128
1616

17-
static DECLARE_RWSEM(trace_event_mutex);
17+
DECLARE_RWSEM(trace_event_mutex);
1818

1919
DEFINE_PER_CPU(struct trace_seq, ftrace_event_seq);
2020
EXPORT_PER_CPU_SYMBOL(ftrace_event_seq);
@@ -702,15 +702,24 @@ int register_ftrace_event(struct trace_event *event)
702702
}
703703
EXPORT_SYMBOL_GPL(register_ftrace_event);
704704

705+
/*
706+
* Used by module code with the trace_event_mutex held for write.
707+
*/
708+
int __unregister_ftrace_event(struct trace_event *event)
709+
{
710+
hlist_del(&event->node);
711+
list_del(&event->list);
712+
return 0;
713+
}
714+
705715
/**
706716
* unregister_ftrace_event - remove a no longer used event
707717
* @event: the event to remove
708718
*/
709719
int unregister_ftrace_event(struct trace_event *event)
710720
{
711721
down_write(&trace_event_mutex);
712-
hlist_del(&event->node);
713-
list_del(&event->list);
722+
__unregister_ftrace_event(event);
714723
up_write(&trace_event_mutex);
715724

716725
return 0;

kernel/trace/trace_output.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ extern struct trace_event *ftrace_find_event(int type);
2727
extern enum print_line_t trace_nop_print(struct trace_iterator *iter,
2828
int flags);
2929

30+
/* used by module unregistering */
31+
extern int __unregister_ftrace_event(struct trace_event *event);
32+
extern struct rw_semaphore trace_event_mutex;
33+
3034
#define MAX_MEMHEX_BYTES 8
3135
#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)
3236

0 commit comments

Comments
 (0)