diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2008-08-14 15:45:09 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-14 04:34:47 -0400 |
commit | 90d595fe5ca4b685465c068907e6e554760abea8 (patch) | |
tree | 03f98454af8c6756177aa053ae7440373007f67d | |
parent | 68bf21aa15c85d2e9b623dcda2b1ed8893275fa1 (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.h | 3 | ||||
-rw-r--r-- | kernel/module.c | 11 | ||||
-rw-r--r-- | kernel/trace/ftrace.c | 5 |
3 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index d4d6ab453b78..4936489f9ed8 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) { } | |||
164 | 164 | ||
165 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 165 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
166 | extern void ftrace_init(void); | 166 | extern void ftrace_init(void); |
167 | extern void ftrace_init_module(unsigned long *start, unsigned long *end); | ||
167 | #else | 168 | #else |
168 | static inline void ftrace_init(void) { } | 169 | static inline void ftrace_init(void) { } |
170 | static inline void | ||
171 | ftrace_init_module(unsigned long *start, unsigned long *end) { } | ||
169 | #endif | 172 | #endif |
170 | 173 | ||
171 | #endif /* _LINUX_FTRACE_H */ | 174 | #endif /* _LINUX_FTRACE_H */ |
diff --git a/kernel/module.c b/kernel/module.c index 661d73db786e..d753fd9d83ec 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/license.h> | 47 | #include <linux/license.h> |
48 | #include <asm/sections.h> | 48 | #include <asm/sections.h> |
49 | #include <linux/tracepoint.h> | 49 | #include <linux/tracepoint.h> |
50 | #include <linux/ftrace.h> | ||
50 | 51 | ||
51 | #if 0 | 52 | #if 0 |
52 | #define DEBUGP printk | 53 | #define DEBUGP printk |
@@ -1834,6 +1835,7 @@ static noinline struct module *load_module(void __user *umod, | |||
1834 | unsigned int markersstringsindex; | 1835 | unsigned int markersstringsindex; |
1835 | unsigned int tracepointsindex; | 1836 | unsigned int tracepointsindex; |
1836 | unsigned int tracepointsstringsindex; | 1837 | unsigned int tracepointsstringsindex; |
1838 | unsigned int mcountindex; | ||
1837 | struct module *mod; | 1839 | struct module *mod; |
1838 | long err = 0; | 1840 | long err = 0; |
1839 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1841 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
@@ -2124,6 +2126,9 @@ static noinline struct module *load_module(void __user *umod, | |||
2124 | tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings, | 2126 | tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings, |
2125 | "__tracepoints_strings"); | 2127 | "__tracepoints_strings"); |
2126 | 2128 | ||
2129 | mcountindex = find_sec(hdr, sechdrs, secstrings, | ||
2130 | "__mcount_loc"); | ||
2131 | |||
2127 | /* Now do relocations. */ | 2132 | /* Now do relocations. */ |
2128 | for (i = 1; i < hdr->e_shnum; i++) { | 2133 | for (i = 1; i < hdr->e_shnum; i++) { |
2129 | const char *strtab = (char *)sechdrs[strindex].sh_addr; | 2134 | const char *strtab = (char *)sechdrs[strindex].sh_addr; |
@@ -2184,6 +2189,12 @@ static noinline struct module *load_module(void __user *umod, | |||
2184 | mod->tracepoints + mod->num_tracepoints); | 2189 | mod->tracepoints + mod->num_tracepoints); |
2185 | #endif | 2190 | #endif |
2186 | } | 2191 | } |
2192 | |||
2193 | if (mcountindex) { | ||
2194 | void *mseg = (void *)sechdrs[mcountindex].sh_addr; | ||
2195 | ftrace_init_module(mseg, mseg + sechdrs[mcountindex].sh_size); | ||
2196 | } | ||
2197 | |||
2187 | err = module_finalize(hdr, sechdrs, mod); | 2198 | err = module_finalize(hdr, sechdrs, mod); |
2188 | if (err < 0) | 2199 | if (err < 0) |
2189 | goto cleanup; | 2200 | goto cleanup; |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index df96d5990c04..ea45bb1c0fd6 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -1541,6 +1541,11 @@ static int ftrace_convert_nops(unsigned long *start, | |||
1541 | return 0; | 1541 | return 0; |
1542 | } | 1542 | } |
1543 | 1543 | ||
1544 | void ftrace_init_module(unsigned long *start, unsigned long *end) | ||
1545 | { | ||
1546 | ftrace_convert_nops(start, end); | ||
1547 | } | ||
1548 | |||
1544 | extern unsigned long __start_mcount_loc[]; | 1549 | extern unsigned long __start_mcount_loc[]; |
1545 | extern unsigned long __stop_mcount_loc[]; | 1550 | extern unsigned long __stop_mcount_loc[]; |
1546 | 1551 | ||