forked from mirrors/linux
		
	lto, workaround: Add workaround for initcall reordering
Work around a LTO gcc problem: when there is no reference to a variable in a module it will be moved to the end of the program. This causes reordering of initcalls which the kernel does not like. Add a dummy reference function to avoid this. The function is deleted by the linker. This replaces a previous much slower workaround. Thanks to Jan "Honza" Hubička for suggesting this technique. Suggested-by: Jan Hubička <hubicka@ucw.cz> Signed-off-by: Andi Kleen <ak@linux.intel.com> Link: http://lkml.kernel.org/r/1391846481-31491-4-git-send-email-ak@linux.intel.com Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
		
							parent
							
								
									128ea04a98
								
							
						
					
					
						commit
						ef1b893c29
					
				
					 1 changed files with 19 additions and 1 deletions
				
			
		|  | @ -163,6 +163,23 @@ extern bool initcall_debug; | |||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| 
 | ||||
| #ifdef CONFIG_LTO | ||||
| /* Work around a LTO gcc problem: when there is no reference to a variable
 | ||||
|  * in a module it will be moved to the end of the program. This causes | ||||
|  * reordering of initcalls which the kernel does not like. | ||||
|  * Add a dummy reference function to avoid this. The function is | ||||
|  * deleted by the linker. | ||||
|  */ | ||||
| #define LTO_REFERENCE_INITCALL(x) \ | ||||
| 	; /* yes this is needed */			\ | ||||
| 	static __used __exit void *reference_##x(void)	\ | ||||
| 	{						\ | ||||
| 		return &x;				\ | ||||
| 	} | ||||
| #else | ||||
| #define LTO_REFERENCE_INITCALL(x) | ||||
| #endif | ||||
| 
 | ||||
| /* initcalls are now grouped by functionality into separate 
 | ||||
|  * subsections. Ordering inside the subsections is determined | ||||
|  * by link order.  | ||||
|  | @ -175,7 +192,8 @@ extern bool initcall_debug; | |||
| 
 | ||||
| #define __define_initcall(fn, id) \ | ||||
| 	static initcall_t __initcall_##fn##id __used \ | ||||
| 	__attribute__((__section__(".initcall" #id ".init"))) = fn | ||||
| 	__attribute__((__section__(".initcall" #id ".init"))) = fn; \ | ||||
| 	LTO_REFERENCE_INITCALL(__initcall_##fn##id) | ||||
| 
 | ||||
| /*
 | ||||
|  * Early initcalls run before initializing SMP. | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Andi Kleen
						Andi Kleen