All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frederic Weisbecker <fweisbec@gmail.com>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: linux-kernel@vger.kernel.org, Ingo Molnar <mingo@elte.hu>,
	Andrew Morton <akpm@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Rusty Russell <rusty@rustcorp.com.au>
Subject: Re: [PATCH 1/5] ftrace: use module notifier for function tracer
Date: Thu, 16 Apr 2009 17:36:19 +0200	[thread overview]
Message-ID: <20090416153618.GB6004@nowhere> (raw)
In-Reply-To: <20090416021928.040177084@goodmis.org>

On Wed, Apr 15, 2009 at 10:18:31PM -0400, Steven Rostedt wrote:
> From: Steven Rostedt <srostedt@redhat.com>
> 
> Impact: fix and clean up
> 
> The hooks in the module code for the function tracer must be called
> before any of that module code runs. The function tracer hooks
> modify the module (replacing calls to mcount to nops). If the code
> is executed while the change occurs, then the CPU can take a GPF.
> 
> To handle the above with a bit of paranoia, I originally implemented
> the hooks as calls directly from the module code.
> 
> After examining the notifier calls, it looks as though the start up
> notify is called before any of the module's code is executed. This makes
> the use of the notify safe with ftrace.
> 
> Only the startup notify is required to be "safe". The shutdown simply
> removes the entries from the ftrace function list, and does not modify
> any code.
> 
> This change has another benefit. It removes a issue with a reverse dependency
> in the mutexes of ftrace_lock and module_mutex.
> 
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> ---
>  include/linux/ftrace.h |    7 ----
>  include/linux/module.h |    4 ++
>  kernel/module.c        |   19 ++++------
>  kernel/trace/ftrace.c  |   90 ++++++++++++++++++++++++++++++++++--------------
>  4 files changed, 75 insertions(+), 45 deletions(-)
> 
> diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> index 53869be..97c83e1 100644
> --- a/include/linux/ftrace.h
> +++ b/include/linux/ftrace.h
> @@ -233,8 +233,6 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
>  
>  extern int skip_trace(unsigned long ip);
>  
> -extern void ftrace_release(void *start, unsigned long size);
> -
>  extern void ftrace_disable_daemon(void);
>  extern void ftrace_enable_daemon(void);
>  #else
> @@ -325,13 +323,8 @@ static inline void __ftrace_enabled_restore(int enabled)
>  
>  #ifdef CONFIG_FTRACE_MCOUNT_RECORD
>  extern void ftrace_init(void);
> -extern void ftrace_init_module(struct module *mod,
> -			       unsigned long *start, unsigned long *end);
>  #else
>  static inline void ftrace_init(void) { }
> -static inline void
> -ftrace_init_module(struct module *mod,
> -		   unsigned long *start, unsigned long *end) { }
>  #endif
>  
>  /*
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 6155fa4..a8f2c0a 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -341,6 +341,10 @@ struct module
>  	struct ftrace_event_call *trace_events;
>  	unsigned int num_trace_events;
>  #endif
> +#ifdef CONFIG_FTRACE_MCOUNT_RECORD
> +	unsigned long *ftrace_callsites;
> +	unsigned int num_ftrace_callsites;
> +#endif
>  
>  #ifdef CONFIG_MODULE_UNLOAD
>  	/* What modules depend on me? */
> diff --git a/kernel/module.c b/kernel/module.c
> index a039470..2383e60 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -1490,9 +1490,6 @@ static void free_module(struct module *mod)
>  	/* Free any allocated parameters. */
>  	destroy_params(mod->kp, mod->num_kp);
>  
> -	/* release any pointers to mcount in this module */
> -	ftrace_release(mod->module_core, mod->core_size);
> -
>  	/* This may be NULL, but that's OK */
>  	module_free(mod, mod->module_init);
>  	kfree(mod->args);
> @@ -1893,11 +1890,9 @@ static noinline struct module *load_module(void __user *umod,
>  	unsigned int symindex = 0;
>  	unsigned int strindex = 0;
>  	unsigned int modindex, versindex, infoindex, pcpuindex;
> -	unsigned int num_mcount;
>  	struct module *mod;
>  	long err = 0;
>  	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
> -	unsigned long *mseg;
>  	mm_segment_t old_fs;
>  
>  	DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
> @@ -2179,7 +2174,13 @@ static noinline struct module *load_module(void __user *umod,
>  					 sizeof(*mod->trace_events),
>  					 &mod->num_trace_events);
>  #endif
> -
> +#ifdef CONFIG_FTRACE_MCOUNT_RECORD
> +	/* sechdrs[0].sh_size is always zero */
> +	mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings,
> +					     "__mcount_loc",
> +					     sizeof(*mod->ftrace_callsites),
> +					     &mod->num_ftrace_callsites);
> +#endif
>  #ifdef CONFIG_MODVERSIONS
>  	if ((mod->num_syms && !mod->crcs)
>  	    || (mod->num_gpl_syms && !mod->gpl_crcs)
> @@ -2244,11 +2245,6 @@ static noinline struct module *load_module(void __user *umod,
>  			dynamic_debug_setup(debug, num_debug);
>  	}
>  
> -	/* sechdrs[0].sh_size is always zero */
> -	mseg = section_objs(hdr, sechdrs, secstrings, "__mcount_loc",
> -			    sizeof(*mseg), &num_mcount);
> -	ftrace_init_module(mod, mseg, mseg + num_mcount);
> -
>  	err = module_finalize(hdr, sechdrs, mod);
>  	if (err < 0)
>  		goto cleanup;
> @@ -2309,7 +2305,6 @@ static noinline struct module *load_module(void __user *umod,
>   cleanup:
>  	kobject_del(&mod->mkobj.kobj);
>  	kobject_put(&mod->mkobj.kobj);
> -	ftrace_release(mod->module_core, mod->core_size);
>   free_unload:
>  	module_unload_free(mod);
>  #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index a234889..5b606f4 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -916,30 +916,6 @@ static void ftrace_free_rec(struct dyn_ftrace *rec)
>  	rec->flags |= FTRACE_FL_FREE;
>  }
>  
> -void ftrace_release(void *start, unsigned long size)
> -{
> -	struct dyn_ftrace *rec;
> -	struct ftrace_page *pg;
> -	unsigned long s = (unsigned long)start;
> -	unsigned long e = s + size;
> -
> -	if (ftrace_disabled || !start)
> -		return;
> -
> -	mutex_lock(&ftrace_lock);
> -	do_for_each_ftrace_rec(pg, rec) {
> -		if ((rec->ip >= s) && (rec->ip < e)) {
> -			/*
> -			 * rec->ip is changed in ftrace_free_rec()
> -			 * It should not between s and e if record was freed.
> -			 */
> -			FTRACE_WARN_ON(rec->flags & FTRACE_FL_FREE);
> -			ftrace_free_rec(rec);
> -		}
> -	} while_for_each_ftrace_rec();
> -	mutex_unlock(&ftrace_lock);
> -}
> -
>  static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
>  {
>  	struct dyn_ftrace *rec;
> @@ -2752,14 +2728,72 @@ static int ftrace_convert_nops(struct module *mod,
>  	return 0;
>  }
>  
> -void ftrace_init_module(struct module *mod,
> -			unsigned long *start, unsigned long *end)
> +#ifdef CONFIG_MODULES
> +void ftrace_release(void *start, void *end)
> +{
> +	struct dyn_ftrace *rec;
> +	struct ftrace_page *pg;
> +	unsigned long s = (unsigned long)start;
> +	unsigned long e = (unsigned long)end;
> +
> +	if (ftrace_disabled || !start || start == end)
> +		return;
> +
> +	mutex_lock(&ftrace_lock);
> +	do_for_each_ftrace_rec(pg, rec) {
> +		if ((rec->ip >= s) && (rec->ip < e)) {
> +			/*
> +			 * rec->ip is changed in ftrace_free_rec()
> +			 * It should not between s and e if record was freed.
> +			 */
> +			FTRACE_WARN_ON(rec->flags & FTRACE_FL_FREE);
> +			ftrace_free_rec(rec);
> +		}
> +	} while_for_each_ftrace_rec();
> +	mutex_unlock(&ftrace_lock);
> +}
> +
> +static void ftrace_init_module(struct module *mod,
> +			       unsigned long *start, unsigned long *end)
>  {
>  	if (ftrace_disabled || start == end)
>  		return;
>  	ftrace_convert_nops(mod, start, end);
>  }
>  
> +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_init_module(mod, mod->ftrace_callsites,
> +				   mod->ftrace_callsites +
> +				   mod->num_ftrace_callsites);
> +		break;
> +	case MODULE_STATE_GOING:
> +		ftrace_release(mod->ftrace_callsites,
> +			       mod->ftrace_callsites +
> +			       mod->num_ftrace_callsites);
> +		break;
> +	}
> +
> +	return 0;
> +}
> +#else
> +static int ftrace_module_notify(struct notifier_block *self,
> +				unsigned long val, void *data)
> +{
> +	return 0;
> +}



You don't seem to like my __init idea :)



> +#endif /* CONFIG_MODULES */
> +
> +struct notifier_block ftrace_module_nb = {
> +	.notifier_call = ftrace_module_notify,
> +	.priority = 0,
> +};
> +



Neither the __initdata_or_module.


Frederic.

>  extern unsigned long __start_mcount_loc[];
>  extern unsigned long __stop_mcount_loc[];
>  
> @@ -2791,6 +2825,10 @@ 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 notifier\n");
> +
>  	return;
>   failed:
>  	ftrace_disabled = 1;
> -- 
> 1.6.2.1
> 
> -- 


  reply	other threads:[~2009-04-16 15:36 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-16  2:18 [PATCH 0/5] [GIT PULL] updates for tip Steven Rostedt
2009-04-16  2:18 ` [PATCH 1/5] ftrace: use module notifier for function tracer Steven Rostedt
2009-04-16 15:36   ` Frederic Weisbecker [this message]
2009-04-16 15:53     ` Steven Rostedt
2009-04-17 11:44   ` Steven Rostedt
2009-04-19 11:25   ` Rusty Russell
2009-04-20 13:57     ` Steven Rostedt
2009-04-21  5:15       ` Rusty Russell
2009-04-21 13:13         ` Steven Rostedt
2009-04-21 13:58           ` Ingo Molnar
2009-04-21 17:51     ` Tim Abbott
2009-04-21 18:17       ` Steven Rostedt
2009-04-21 18:47         ` Tim Abbott
2009-04-22  9:16       ` Ingo Molnar
2009-04-22 22:20         ` Tim Abbott
2009-04-22 22:57           ` Masami Hiramatsu
2009-04-23 19:40             ` Anders Kaseorg
2009-04-23 19:57               ` Mathieu Desnoyers
2009-04-23 22:31                 ` Tim Abbott
2009-04-24  3:11                   ` Masami Hiramatsu
2009-04-23 20:06               ` Masami Hiramatsu
2009-04-16  2:18 ` [PATCH 2/5] tracing/events: add startup tests for events Steven Rostedt
2009-04-16  8:39   ` [PATCH] tracing: add #include <linux/delay.h> to fix build failure in test_work() Ingo Molnar
2009-04-16 14:08     ` Steven Rostedt
2009-04-17  0:30       ` Ingo Molnar
2009-04-16 15:41   ` [PATCH 2/5] tracing/events: add startup tests for events Frederic Weisbecker
2009-04-16 15:51     ` Steven Rostedt
2009-04-16 16:02   ` Frederic Weisbecker
2009-04-16  2:18 ` [PATCH 3/5] tracing/events: add rcu locking around trace event prints Steven Rostedt
2009-04-17 14:08   ` Steven Rostedt
2009-04-17 15:20     ` Jeremy Fitzhardinge
2009-04-17 15:42       ` Steven Rostedt
2009-04-17 23:53         ` Jeremy Fitzhardinge
2009-04-17 16:18     ` Theodore Tso
2009-04-17 16:32       ` Jeremy Fitzhardinge
2009-04-17 16:41         ` Steven Rostedt
2009-05-07  2:10   ` Steven Rostedt
2009-05-07 11:32     ` Ingo Molnar
2009-05-07 13:10       ` Steven Rostedt
2009-04-16  2:18 ` [PATCH 4/5] tracing/events/ring-buffer: expose format of ring buffer headers to users Steven Rostedt
2009-04-16  2:18 ` [PATCH 5/5] tracing: add saved_cmdlines file to show cached task comms Steven Rostedt
2009-04-16 15:54   ` Frederic Weisbecker
2009-04-16 15:58     ` Steven Rostedt
2009-04-16 16:05       ` Frederic Weisbecker
2009-04-16  9:51 ` [PATCH 0/5] [GIT PULL] updates for tip Ingo Molnar
2009-04-16  9:53   ` Ingo Molnar
2009-04-16 13:52   ` Steven Rostedt
2009-04-16 16:12     ` Ingo Molnar
2009-04-16 16:22       ` Steven Rostedt
2009-04-17  0:29         ` Ingo Molnar
2009-04-16 16:30       ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090416153618.GB6004@nowhere \
    --to=fweisbec@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=rusty@rustcorp.com.au \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.