Explorar o código

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>
Steven Rostedt %!s(int64=16) %!d(string=hai) anos
pai
achega
90d595fe5c
Modificáronse 3 ficheiros con 19 adicións e 0 borrados
  1. 3 0
      include/linux/ftrace.h
  2. 11 0
      kernel/module.c
  3. 5 0
      kernel/trace/ftrace.c

+ 3 - 0
include/linux/ftrace.h

@@ -164,8 +164,11 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
 
 
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 extern void ftrace_init(void);
 extern void ftrace_init(void);
+extern void ftrace_init_module(unsigned long *start, unsigned long *end);
 #else
 #else
 static inline void ftrace_init(void) { }
 static inline void ftrace_init(void) { }
+static inline void
+ftrace_init_module(unsigned long *start, unsigned long *end) { }
 #endif
 #endif
 
 
 #endif /* _LINUX_FTRACE_H */
 #endif /* _LINUX_FTRACE_H */

+ 11 - 0
kernel/module.c

@@ -47,6 +47,7 @@
 #include <linux/license.h>
 #include <linux/license.h>
 #include <asm/sections.h>
 #include <asm/sections.h>
 #include <linux/tracepoint.h>
 #include <linux/tracepoint.h>
+#include <linux/ftrace.h>
 
 
 #if 0
 #if 0
 #define DEBUGP printk
 #define DEBUGP printk
@@ -1834,6 +1835,7 @@ static noinline struct module *load_module(void __user *umod,
 	unsigned int markersstringsindex;
 	unsigned int markersstringsindex;
 	unsigned int tracepointsindex;
 	unsigned int tracepointsindex;
 	unsigned int tracepointsstringsindex;
 	unsigned int tracepointsstringsindex;
+	unsigned int mcountindex;
 	struct module *mod;
 	struct module *mod;
 	long err = 0;
 	long err = 0;
 	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
 	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,
 	tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings,
 					"__tracepoints_strings");
 					"__tracepoints_strings");
 
 
+	mcountindex = find_sec(hdr, sechdrs, secstrings,
+			       "__mcount_loc");
+
 	/* Now do relocations. */
 	/* Now do relocations. */
 	for (i = 1; i < hdr->e_shnum; i++) {
 	for (i = 1; i < hdr->e_shnum; i++) {
 		const char *strtab = (char *)sechdrs[strindex].sh_addr;
 		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);
 			mod->tracepoints + mod->num_tracepoints);
 #endif
 #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);
 	err = module_finalize(hdr, sechdrs, mod);
 	if (err < 0)
 	if (err < 0)
 		goto cleanup;
 		goto cleanup;

+ 5 - 0
kernel/trace/ftrace.c

@@ -1541,6 +1541,11 @@ static int ftrace_convert_nops(unsigned long *start,
 	return 0;
 	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 __start_mcount_loc[];
 extern unsigned long __stop_mcount_loc[];
 extern unsigned long __stop_mcount_loc[];