diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/ftrace.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index ce8c3d68292f..98ca94a41819 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -3996,37 +3996,51 @@ static void ftrace_init_module(struct module *mod, | |||
3996 | ftrace_process_locs(mod, start, end); | 3996 | ftrace_process_locs(mod, start, end); |
3997 | } | 3997 | } |
3998 | 3998 | ||
3999 | static int ftrace_module_notify(struct notifier_block *self, | 3999 | static int ftrace_module_notify_enter(struct notifier_block *self, |
4000 | unsigned long val, void *data) | 4000 | unsigned long val, void *data) |
4001 | { | 4001 | { |
4002 | struct module *mod = data; | 4002 | struct module *mod = data; |
4003 | 4003 | ||
4004 | switch (val) { | 4004 | if (val == MODULE_STATE_COMING) |
4005 | case MODULE_STATE_COMING: | ||
4006 | ftrace_init_module(mod, mod->ftrace_callsites, | 4005 | ftrace_init_module(mod, mod->ftrace_callsites, |
4007 | mod->ftrace_callsites + | 4006 | mod->ftrace_callsites + |
4008 | mod->num_ftrace_callsites); | 4007 | mod->num_ftrace_callsites); |
4009 | break; | 4008 | return 0; |
4010 | case MODULE_STATE_GOING: | 4009 | } |
4010 | |||
4011 | static int ftrace_module_notify_exit(struct notifier_block *self, | ||
4012 | unsigned long val, void *data) | ||
4013 | { | ||
4014 | struct module *mod = data; | ||
4015 | |||
4016 | if (val == MODULE_STATE_GOING) | ||
4011 | ftrace_release_mod(mod); | 4017 | ftrace_release_mod(mod); |
4012 | break; | ||
4013 | } | ||
4014 | 4018 | ||
4015 | return 0; | 4019 | return 0; |
4016 | } | 4020 | } |
4017 | #else | 4021 | #else |
4018 | static int ftrace_module_notify(struct notifier_block *self, | 4022 | static int ftrace_module_notify_enter(struct notifier_block *self, |
4019 | unsigned long val, void *data) | 4023 | unsigned long val, void *data) |
4024 | { | ||
4025 | return 0; | ||
4026 | } | ||
4027 | static int ftrace_module_notify_exit(struct notifier_block *self, | ||
4028 | unsigned long val, void *data) | ||
4020 | { | 4029 | { |
4021 | return 0; | 4030 | return 0; |
4022 | } | 4031 | } |
4023 | #endif /* CONFIG_MODULES */ | 4032 | #endif /* CONFIG_MODULES */ |
4024 | 4033 | ||
4025 | struct notifier_block ftrace_module_nb = { | 4034 | struct notifier_block ftrace_module_enter_nb = { |
4026 | .notifier_call = ftrace_module_notify, | 4035 | .notifier_call = ftrace_module_notify_enter, |
4027 | .priority = INT_MAX, /* Run before anything that can use kprobes */ | 4036 | .priority = INT_MAX, /* Run before anything that can use kprobes */ |
4028 | }; | 4037 | }; |
4029 | 4038 | ||
4039 | struct notifier_block ftrace_module_exit_nb = { | ||
4040 | .notifier_call = ftrace_module_notify_exit, | ||
4041 | .priority = INT_MIN, /* Run after anything that can remove kprobes */ | ||
4042 | }; | ||
4043 | |||
4030 | extern unsigned long __start_mcount_loc[]; | 4044 | extern unsigned long __start_mcount_loc[]; |
4031 | extern unsigned long __stop_mcount_loc[]; | 4045 | extern unsigned long __stop_mcount_loc[]; |
4032 | 4046 | ||
@@ -4058,9 +4072,13 @@ void __init ftrace_init(void) | |||
4058 | __start_mcount_loc, | 4072 | __start_mcount_loc, |
4059 | __stop_mcount_loc); | 4073 | __stop_mcount_loc); |
4060 | 4074 | ||
4061 | ret = register_module_notifier(&ftrace_module_nb); | 4075 | ret = register_module_notifier(&ftrace_module_enter_nb); |
4076 | if (ret) | ||
4077 | pr_warning("Failed to register trace ftrace module enter notifier\n"); | ||
4078 | |||
4079 | ret = register_module_notifier(&ftrace_module_exit_nb); | ||
4062 | if (ret) | 4080 | if (ret) |
4063 | pr_warning("Failed to register trace ftrace module notifier\n"); | 4081 | pr_warning("Failed to register trace ftrace module exit notifier\n"); |
4064 | 4082 | ||
4065 | set_ftrace_early_filters(); | 4083 | set_ftrace_early_filters(); |
4066 | 4084 | ||