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:
Родитель
128ea04a98
Коммит
ef1b893c29
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче