Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef1b893c authored by Andi Kleen's avatar Andi Kleen Committed by H. Peter Anvin
Browse files

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: default avatarJan Hubička <hubicka@ucw.cz>
Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/1391846481-31491-4-git-send-email-ak@linux.intel.com


Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent 128ea04a
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -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.