Re: [PATCH v2 1/2] ftrace/module: remove ftrace module notifier

From: Petr Mladek
Date: Thu Feb 04 2016 - 08:27:59 EST


On Mon 2016-02-01 20:17:35, Jessica Yu wrote:
> Remove the ftrace module notifier in favor of directly calling
> ftrace_module_enable() and ftrace_release_mod() in the module loader.
> Hard-coding the function calls directly in the module loader removes
> dependence on the module notifier call chain and provides better
> visibility and control over what gets called when, which is important
> to kernel utilities such as livepatch.
>
> Signed-off-by: Jessica Yu <jeyu@xxxxxxxxxx>
> ---
> include/linux/ftrace.h | 6 ++++--
> kernel/module.c | 4 ++++
> kernel/trace/ftrace.c | 36 +-----------------------------------
> 3 files changed, 9 insertions(+), 37 deletions(-)
>
> diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> index 81de712..c2b340e 100644
> --- a/include/linux/ftrace.h
> +++ b/include/linux/ftrace.h
> @@ -603,6 +603,7 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
>
> extern int skip_trace(unsigned long ip);
> extern void ftrace_module_init(struct module *mod);
> +extern void ftrace_module_enable(struct module *mod);
> extern void ftrace_release_mod(struct module *mod);
>
> extern void ftrace_disable_daemon(void);
> @@ -612,8 +613,9 @@ static inline int skip_trace(unsigned long ip) { return 0; }
> static inline int ftrace_force_update(void) { return 0; }
> static inline void ftrace_disable_daemon(void) { }
> static inline void ftrace_enable_daemon(void) { }
> -static inline void ftrace_release_mod(struct module *mod) {}
> -static inline void ftrace_module_init(struct module *mod) {}
> +static inline void ftrace_module_init(struct module *mod) { }
> +static inline void ftrace_module_enable(struct module *mod) { }
> +static inline void ftrace_release_mod(struct module *mod) { }
> static inline __init int register_ftrace_command(struct ftrace_func_command *cmd)
> {
> return -EINVAL;
> diff --git a/kernel/module.c b/kernel/module.c
> index 8358f46..b05d466 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -981,6 +981,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
> mod->exit();
> blocking_notifier_call_chain(&module_notify_list,
> MODULE_STATE_GOING, mod);
> + ftrace_release_mod(mod);
> +
> async_synchronize_full();
>
> /* Store the name of the last unloaded module for diagnostic purposes */
> @@ -3295,6 +3297,7 @@ fail:
> module_put(mod);
> blocking_notifier_call_chain(&module_notify_list,
> MODULE_STATE_GOING, mod);
> + ftrace_release_mod(mod);
> free_module(mod);
> wake_up_all(&module_wq);
> return ret;
> @@ -3371,6 +3374,7 @@ static int complete_formation(struct module *mod, struct load_info *info)
> mod->state = MODULE_STATE_COMING;
> mutex_unlock(&module_mutex);
>
> + ftrace_module_enable(mod);
> blocking_notifier_call_chain(&module_notify_list,
> MODULE_STATE_COMING, mod);
> return 0;

Also we need to call ftrace_release_mod() in bug_cleanup:
goto target in load_module(). Otherwise, it will stay
enabled when, e.g. parse_args() fails.

Best Regards,
Petr