Skip to content

Commit ef1b893

Browse files
Andi KleenH. Peter Anvin
authored andcommitted
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 <[email protected]> Signed-off-by: Andi Kleen <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: H. Peter Anvin <[email protected]>
1 parent 128ea04 commit ef1b893

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

include/linux/init.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,23 @@ extern bool initcall_debug;
163163

164164
#ifndef __ASSEMBLY__
165165

166+
#ifdef CONFIG_LTO
167+
/* Work around a LTO gcc problem: when there is no reference to a variable
168+
* in a module it will be moved to the end of the program. This causes
169+
* reordering of initcalls which the kernel does not like.
170+
* Add a dummy reference function to avoid this. The function is
171+
* deleted by the linker.
172+
*/
173+
#define LTO_REFERENCE_INITCALL(x) \
174+
; /* yes this is needed */ \
175+
static __used __exit void *reference_##x(void) \
176+
{ \
177+
return &x; \
178+
}
179+
#else
180+
#define LTO_REFERENCE_INITCALL(x)
181+
#endif
182+
166183
/* initcalls are now grouped by functionality into separate
167184
* subsections. Ordering inside the subsections is determined
168185
* by link order.
@@ -175,7 +192,8 @@ extern bool initcall_debug;
175192

176193
#define __define_initcall(fn, id) \
177194
static initcall_t __initcall_##fn##id __used \
178-
__attribute__((__section__(".initcall" #id ".init"))) = fn
195+
__attribute__((__section__(".initcall" #id ".init"))) = fn; \
196+
LTO_REFERENCE_INITCALL(__initcall_##fn##id)
179197

180198
/*
181199
* Early initcalls run before initializing SMP.

0 commit comments

Comments
 (0)