aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/ftrace.c46
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
3999static int ftrace_module_notify(struct notifier_block *self, 3999static 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
4011static 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
4018static int ftrace_module_notify(struct notifier_block *self, 4022static 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}
4027static 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
4025struct notifier_block ftrace_module_nb = { 4034struct 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
4039struct 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
4030extern unsigned long __start_mcount_loc[]; 4044extern unsigned long __start_mcount_loc[];
4031extern unsigned long __stop_mcount_loc[]; 4045extern 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