summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2008-08-14 15:45:09 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-14 10:34:47 +0200
commit90d595fe5ca4b685465c068907e6e554760abea8 (patch)
tree03f98454af8c6756177aa053ae7440373007f67d
parent68bf21aa15c85d2e9b623dcda2b1ed8893275fa1 (diff)
ftrace: enable mcount recording for modules
This patch enables the loading of the __mcount_section of modules and changing all the callers of mcount into nops. The modification is done before the init_module function is called, so again, we do not need to use kstop_machine to make these changes. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/ftrace.h3
-rw-r--r--kernel/module.c11
-rw-r--r--kernel/trace/ftrace.c5
3 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index d4d6ab453b7..4936489f9ed 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -164,8 +164,11 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
#ifdef CONFIG_FTRACE_MCOUNT_RECORD
extern void ftrace_init(void);
+extern void ftrace_init_module(unsigned long *start, unsigned long *end);
#else
static inline void ftrace_init(void) { }
+static inline void
+ftrace_init_module(unsigned long *start, unsigned long *end) { }
#endif
#endif /* _LINUX_FTRACE_H */
diff --git a/kernel/module.c b/kernel/module.c
index 661d73db786..d753fd9d83e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -47,6 +47,7 @@
#include <linux/license.h>
#include <asm/sections.h>
#include <linux/tracepoint.h>
+#include <linux/ftrace.h>
#if 0
#define DEBUGP printk
@@ -1834,6 +1835,7 @@ static noinline struct module *load_module(void __user *umod,
unsigned int markersstringsindex;
unsigned int tracepointsindex;
unsigned int tracepointsstringsindex;
+ unsigned int mcountindex;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -2124,6 +2126,9 @@ static noinline struct module *load_module(void __user *umod,
tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings,
"__tracepoints_strings");
+ mcountindex = find_sec(hdr, sechdrs, secstrings,
+ "__mcount_loc");
+
/* Now do relocations. */
for (i = 1; i < hdr->e_shnum; i++) {
const char *strtab = (char *)sechdrs[strindex].sh_addr;
@@ -2184,6 +2189,12 @@ static noinline struct module *load_module(void __user *umod,
mod->tracepoints + mod->num_tracepoints);
#endif
}
+
+ if (mcountindex) {
+ void *mseg = (void *)sechdrs[mcountindex].sh_addr;
+ ftrace_init_module(mseg, mseg + sechdrs[mcountindex].sh_size);
+ }
+
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
goto cleanup;
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index df96d5990c0..ea45bb1c0fd 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1541,6 +1541,11 @@ static int ftrace_convert_nops(unsigned long *start,
return 0;
}
+void ftrace_init_module(unsigned long *start, unsigned long *end)
+{
+ ftrace_convert_nops(start, end);
+}
+
extern unsigned long __start_mcount_loc[];
extern unsigned long __stop_mcount_loc[];