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