aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/init.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/init.h')
-rw-r--r--include/linux/init.h38
1 files changed, 13 insertions, 25 deletions
diff --git a/include/linux/init.h b/include/linux/init.h
index 6935d02474aa..e571fec4bb28 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -150,24 +150,8 @@ extern bool initcall_debug;
150 150
151#ifndef __ASSEMBLY__ 151#ifndef __ASSEMBLY__
152 152
153#ifdef CONFIG_LTO 153/*
154/* Work around a LTO gcc problem: when there is no reference to a variable 154 * initcalls are now grouped by functionality into separate
155 * in a module it will be moved to the end of the program. This causes
156 * reordering of initcalls which the kernel does not like.
157 * Add a dummy reference function to avoid this. The function is
158 * deleted by the linker.
159 */
160#define LTO_REFERENCE_INITCALL(x) \
161 ; /* yes this is needed */ \
162 static __used __exit void *reference_##x(void) \
163 { \
164 return &x; \
165 }
166#else
167#define LTO_REFERENCE_INITCALL(x)
168#endif
169
170/* initcalls are now grouped by functionality into separate
171 * subsections. Ordering inside the subsections is determined 155 * subsections. Ordering inside the subsections is determined
172 * by link order. 156 * by link order.
173 * For backwards compatibility, initcall() puts the call in 157 * For backwards compatibility, initcall() puts the call in
@@ -175,12 +159,16 @@ extern bool initcall_debug;
175 * 159 *
176 * The `id' arg to __define_initcall() is needed so that multiple initcalls 160 * The `id' arg to __define_initcall() is needed so that multiple initcalls
177 * can point at the same handler without causing duplicate-symbol build errors. 161 * can point at the same handler without causing duplicate-symbol build errors.
162 *
163 * Initcalls are run by placing pointers in initcall sections that the
164 * kernel iterates at runtime. The linker can do dead code / data elimination
165 * and remove that completely, so the initcall sections have to be marked
166 * as KEEP() in the linker script.
178 */ 167 */
179 168
180#define __define_initcall(fn, id) \ 169#define __define_initcall(fn, id) \
181 static initcall_t __initcall_##fn##id __used \ 170 static initcall_t __initcall_##fn##id __used \
182 __attribute__((__section__(".initcall" #id ".init"))) = fn; \ 171 __attribute__((__section__(".initcall" #id ".init"))) = fn;
183 LTO_REFERENCE_INITCALL(__initcall_##fn##id)
184 172
185/* 173/*
186 * Early initcalls run before initializing SMP. 174 * Early initcalls run before initializing SMP.
@@ -216,15 +204,15 @@ extern bool initcall_debug;
216 204
217#define __initcall(fn) device_initcall(fn) 205#define __initcall(fn) device_initcall(fn)
218 206
219#define __exitcall(fn) \ 207#define __exitcall(fn) \
220 static exitcall_t __exitcall_##fn __exit_call = fn 208 static exitcall_t __exitcall_##fn __exit_call = fn
221 209
222#define console_initcall(fn) \ 210#define console_initcall(fn) \
223 static initcall_t __initcall_##fn \ 211 static initcall_t __initcall_##fn \
224 __used __section(.con_initcall.init) = fn 212 __used __section(.con_initcall.init) = fn
225 213
226#define security_initcall(fn) \ 214#define security_initcall(fn) \
227 static initcall_t __initcall_##fn \ 215 static initcall_t __initcall_##fn \
228 __used __section(.security_initcall.init) = fn 216 __used __section(.security_initcall.init) = fn
229 217
230struct obs_kernel_param { 218struct obs_kernel_param {