diff options
| -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 | ||
