Skip to content

Commit

Permalink
lto, workaround: Add workaround for initcall reordering
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andi Kleen authored and H. Peter Anvin committed Feb 14, 2014
1 parent 128ea04 commit ef1b893
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion include/linux/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down

0 comments on commit ef1b893

Please sign in to comment.