mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	kernel: tracepoints: add support for relative references
To avoid the need for relocating absolute references to tracepoint structures at boot time when running relocatable kernels (which may take a disproportionate amount of space), add the option to emit these tables as relative references instead. Link: http://lkml.kernel.org/r/20180704083651.24360-7-ard.biesheuvel@linaro.org Acked-by: Michael Ellerman <mpe@ellerman.id.au> Acked-by: Ingo Molnar <mingo@kernel.org> Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: James Morris <james.morris@microsoft.com> Cc: James Morris <jmorris@namei.org> Cc: Jessica Yu <jeyu@kernel.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Kees Cook <keescook@chromium.org> Cc: Nicolas Pitre <nico@linaro.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Petr Mladek <pmladek@suse.com> Cc: Russell King <linux@armlinux.org.uk> Cc: "Serge E. Hallyn" <serge@hallyn.com> Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Cc: Thomas Garnier <thgarnie@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									c9d8b55fa0
								
							
						
					
					
						commit
						46e0c9be20
					
				
					 2 changed files with 41 additions and 27 deletions
				
			
		|  | @ -249,6 +249,19 @@ extern void syscall_unregfunc(void); | |||
| 		return static_key_false(&__tracepoint_##name.key);	\ | ||||
| 	} | ||||
| 
 | ||||
| #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | ||||
| #define __TRACEPOINT_ENTRY(name)					\ | ||||
| 	asm("	.section \"__tracepoints_ptrs\", \"a\"		\n"	\ | ||||
| 	    "	.balign 4					\n"	\ | ||||
| 	    "	.long 	__tracepoint_" #name " - .		\n"	\ | ||||
| 	    "	.previous					\n") | ||||
| #else | ||||
| #define __TRACEPOINT_ENTRY(name)					 \ | ||||
| 	static struct tracepoint * const __tracepoint_ptr_##name __used	 \ | ||||
| 	__attribute__((section("__tracepoints_ptrs"))) =		 \ | ||||
| 		&__tracepoint_##name | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * We have no guarantee that gcc and the linker won't up-align the tracepoint | ||||
|  * structures, so we create an array of pointers that will be used for iteration | ||||
|  | @ -258,11 +271,9 @@ extern void syscall_unregfunc(void); | |||
| 	static const char __tpstrtab_##name[]				 \ | ||||
| 	__attribute__((section("__tracepoints_strings"))) = #name;	 \ | ||||
| 	struct tracepoint __tracepoint_##name				 \ | ||||
| 	__attribute__((section("__tracepoints"))) =			 \ | ||||
| 	__attribute__((section("__tracepoints"), used)) =		 \ | ||||
| 		{ __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\ | ||||
| 	static struct tracepoint * const __tracepoint_ptr_##name __used	 \ | ||||
| 	__attribute__((section("__tracepoints_ptrs"))) =		 \ | ||||
| 		&__tracepoint_##name; | ||||
| 	__TRACEPOINT_ENTRY(name); | ||||
| 
 | ||||
| #define DEFINE_TRACE(name)						\ | ||||
| 	DEFINE_TRACE_FN(name, NULL, NULL); | ||||
|  |  | |||
|  | @ -371,6 +371,27 @@ int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data) | |||
| } | ||||
| EXPORT_SYMBOL_GPL(tracepoint_probe_unregister); | ||||
| 
 | ||||
| static void for_each_tracepoint_range(struct tracepoint * const *begin, | ||||
| 		struct tracepoint * const *end, | ||||
| 		void (*fct)(struct tracepoint *tp, void *priv), | ||||
| 		void *priv) | ||||
| { | ||||
| 	if (!begin) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (IS_ENABLED(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)) { | ||||
| 		const int *iter; | ||||
| 
 | ||||
| 		for (iter = (const int *)begin; iter < (const int *)end; iter++) | ||||
| 			fct(offset_to_ptr(iter), priv); | ||||
| 	} else { | ||||
| 		struct tracepoint * const *iter; | ||||
| 
 | ||||
| 		for (iter = begin; iter < end; iter++) | ||||
| 			fct(*iter, priv); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_MODULES | ||||
| bool trace_module_has_bad_taint(struct module *mod) | ||||
| { | ||||
|  | @ -435,15 +456,9 @@ EXPORT_SYMBOL_GPL(unregister_tracepoint_module_notifier); | |||
|  * Ensure the tracer unregistered the module's probes before the module | ||||
|  * teardown is performed. Prevents leaks of probe and data pointers. | ||||
|  */ | ||||
| static void tp_module_going_check_quiescent(struct tracepoint * const *begin, | ||||
| 		struct tracepoint * const *end) | ||||
| static void tp_module_going_check_quiescent(struct tracepoint *tp, void *priv) | ||||
| { | ||||
| 	struct tracepoint * const *iter; | ||||
| 
 | ||||
| 	if (!begin) | ||||
| 		return; | ||||
| 	for (iter = begin; iter < end; iter++) | ||||
| 		WARN_ON_ONCE((*iter)->funcs); | ||||
| 	WARN_ON_ONCE(tp->funcs); | ||||
| } | ||||
| 
 | ||||
| static int tracepoint_module_coming(struct module *mod) | ||||
|  | @ -494,8 +509,9 @@ static void tracepoint_module_going(struct module *mod) | |||
| 			 * Called the going notifier before checking for | ||||
| 			 * quiescence. | ||||
| 			 */ | ||||
| 			tp_module_going_check_quiescent(mod->tracepoints_ptrs, | ||||
| 				mod->tracepoints_ptrs + mod->num_tracepoints); | ||||
| 			for_each_tracepoint_range(mod->tracepoints_ptrs, | ||||
| 				mod->tracepoints_ptrs + mod->num_tracepoints, | ||||
| 				tp_module_going_check_quiescent, NULL); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -547,19 +563,6 @@ static __init int init_tracepoints(void) | |||
| __initcall(init_tracepoints); | ||||
| #endif /* CONFIG_MODULES */ | ||||
| 
 | ||||
| static void for_each_tracepoint_range(struct tracepoint * const *begin, | ||||
| 		struct tracepoint * const *end, | ||||
| 		void (*fct)(struct tracepoint *tp, void *priv), | ||||
| 		void *priv) | ||||
| { | ||||
| 	struct tracepoint * const *iter; | ||||
| 
 | ||||
| 	if (!begin) | ||||
| 		return; | ||||
| 	for (iter = begin; iter < end; iter++) | ||||
| 		fct(*iter, priv); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * for_each_kernel_tracepoint - iteration on all kernel tracepoints | ||||
|  * @fct: callback | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Ard Biesheuvel
						Ard Biesheuvel