Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1323688 > unrolled thread

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

Started byJessica Yu <jeyu@redhat.com>
First post2016-02-02 02:20 +0100
Last post2016-02-04 16:40 +0100
Articles 5 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v2 1/2] ftrace/module: remove ftrace module notifier Jessica Yu <jeyu@redhat.com> - 2016-02-02 02:20 +0100
    Re: [PATCH v2 1/2] ftrace/module: remove ftrace module notifier Petr Mladek <pmladek@suse.com> - 2016-02-04 14:30 +0100
      Re: [PATCH v2 1/2] ftrace/module: remove ftrace module notifier Steven Rostedt <rostedt@goodmis.org> - 2016-02-04 15:20 +0100
        Re: [PATCH v2 1/2] ftrace/module: remove ftrace module notifier Petr Mladek <pmladek@suse.com> - 2016-02-04 16:30 +0100
          Re: [PATCH v2 1/2] ftrace/module: remove ftrace module notifier Steven Rostedt <rostedt@goodmis.org> - 2016-02-04 16:40 +0100

#1323688 — [PATCH v2 1/2] ftrace/module: remove ftrace module notifier

FromJessica Yu <jeyu@redhat.com>
Date2016-02-02 02:20 +0100
Subject[PATCH v2 1/2] ftrace/module: remove ftrace module notifier
Message-ID<qXxNo-38h-3@gated-at.bofh.it>
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@redhat.com>
---
 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;
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index eca592f..57a6eea 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -4961,7 +4961,7 @@ void ftrace_release_mod(struct module *mod)
 	mutex_unlock(&ftrace_lock);
 }
 
-static void ftrace_module_enable(struct module *mod)
+void ftrace_module_enable(struct module *mod)
 {
 	struct dyn_ftrace *rec;
 	struct ftrace_page *pg;
@@ -5038,38 +5038,8 @@ void ftrace_module_init(struct module *mod)
 	ftrace_process_locs(mod, mod->ftrace_callsites,
 			    mod->ftrace_callsites + mod->num_ftrace_callsites);
 }
-
-static int ftrace_module_notify(struct notifier_block *self,
-				unsigned long val, void *data)
-{
-	struct module *mod = data;
-
-	switch (val) {
-	case MODULE_STATE_COMING:
-		ftrace_module_enable(mod);
-		break;
-	case MODULE_STATE_GOING:
-		ftrace_release_mod(mod);
-		break;
-	default:
-		break;
-	}
-
-	return 0;
-}
-#else
-static int ftrace_module_notify(struct notifier_block *self,
-				unsigned long val, void *data)
-{
-	return 0;
-}
 #endif /* CONFIG_MODULES */
 
-struct notifier_block ftrace_module_nb = {
-	.notifier_call = ftrace_module_notify,
-	.priority = INT_MIN,	/* Run after anything that can remove kprobes */
-};
-
 void __init ftrace_init(void)
 {
 	extern unsigned long __start_mcount_loc[];
@@ -5098,10 +5068,6 @@ void __init ftrace_init(void)
 				  __start_mcount_loc,
 				  __stop_mcount_loc);
 
-	ret = register_module_notifier(&ftrace_module_nb);
-	if (ret)
-		pr_warning("Failed to register trace ftrace module exit notifier\n");
-
 	set_ftrace_early_filters();
 
 	return;
-- 
2.4.3

[toc] | [next] | [standalone]


#1326799

FromPetr Mladek <pmladek@suse.com>
Date2016-02-04 14:30 +0100
Message-ID<qYs8X-Kq-37@gated-at.bofh.it>
In reply to#1323688
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@redhat.com>
> ---
>  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

[toc] | [prev] | [next] | [standalone]


#1326863

FromSteven Rostedt <rostedt@goodmis.org>
Date2016-02-04 15:20 +0100
Message-ID<qYsVk-1nc-35@gated-at.bofh.it>
In reply to#1326799
On Thu, 4 Feb 2016 14:27:51 +0100
Petr Mladek <pmladek@suse.com> wrote:


> > +	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.

Look farther down (after free_module:), it's already there.

-- Steve

[toc] | [prev] | [next] | [standalone]


#1326921

FromPetr Mladek <pmladek@suse.com>
Date2016-02-04 16:30 +0100
Message-ID<qYu14-3JT-9@gated-at.bofh.it>
In reply to#1326863
On Thu 2016-02-04 09:18:01, Steven Rostedt wrote:
> On Thu, 4 Feb 2016 14:27:51 +0100
> Petr Mladek <pmladek@suse.com> wrote:
> 
> 
> > > +	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.
> 
> Look farther down (after free_module:), it's already there.

Ah, I see. ftrace_release_mod() is called there on an unexpected
location. Error paths typically do actions in the reverse order
in compare with the normal paths :-)

Thanks for the pointer,
Petr

[toc] | [prev] | [next] | [standalone]


#1326928

FromSteven Rostedt <rostedt@goodmis.org>
Date2016-02-04 16:40 +0100
Message-ID<qYuaK-3NO-13@gated-at.bofh.it>
In reply to#1326921
On Thu, 4 Feb 2016 16:21:20 +0100
Petr Mladek <pmladek@suse.com> wrote:

> Ah, I see. ftrace_release_mod() is called there on an unexpected
> location. Error paths typically do actions in the reverse order
> in compare with the normal paths :-)

And that's why there's a comment above it describing why it's not in
the normal "reverse" location.

-- Steve

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web