Message ID | 20200624203200.78870-10-samitolvanen@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | add support for Clang LTO | expand |
Hi Sami, Thank you for the patch! Yet something to improve: [auto build test ERROR on 26e122e97a3d0390ebec389347f64f3730fdf48f] url: https://github.com/0day-ci/linux/commits/Sami-Tolvanen/add-support-for-Clang-LTO/20200625-043816 base: 26e122e97a3d0390ebec389347f64f3730fdf48f config: m68k-defconfig (attached as .config) compiler: m68k-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=m68k If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All error/warnings (new ones prefixed by >>): In file included from arch/m68k/include/asm/io_mm.h:25, from arch/m68k/include/asm/io.h:8, from include/linux/io.h:13, from include/linux/irq.h:20, from include/asm-generic/hardirq.h:13, from ./arch/m68k/include/generated/asm/hardirq.h:1, from include/linux/hardirq.h:10, from include/linux/interrupt.h:11, from drivers/ide/gayle.c:13: arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsb': arch/m68k/include/asm/raw_io.h:83:7: warning: variable '__w' set but not used [-Wunused-but-set-variable] 83 | ({u8 __w, __v = (b); u32 _addr = ((u32) (addr)); \ | ^~~ arch/m68k/include/asm/raw_io.h:430:3: note: in expansion of macro 'rom_out_8' 430 | rom_out_8(port, *buf++); | ^~~~~~~~~ arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsw': arch/m68k/include/asm/raw_io.h:86:8: warning: variable '__w' set but not used [-Wunused-but-set-variable] 86 | ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \ | ^~~ arch/m68k/include/asm/raw_io.h:448:3: note: in expansion of macro 'rom_out_be16' 448 | rom_out_be16(port, *buf++); | ^~~~~~~~~~~~ arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsw_swapw': arch/m68k/include/asm/raw_io.h:90:8: warning: variable '__w' set but not used [-Wunused-but-set-variable] 90 | ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \ | ^~~ arch/m68k/include/asm/raw_io.h:466:3: note: in expansion of macro 'rom_out_le16' 466 | rom_out_le16(port, *buf++); | ^~~~~~~~~~~~ In file included from arch/m68k/include/asm/bug.h:32, from include/linux/bug.h:5, from include/linux/mmdebug.h:5, from include/linux/mm.h:9, from drivers/ide/gayle.c:12: include/linux/dma-mapping.h: In function 'dma_map_resource': arch/m68k/include/asm/page_mm.h:169:49: warning: ordered comparison of pointer with null pointer [-Wextra] 169 | #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory) | ^~ include/asm-generic/bug.h:144:27: note: in definition of macro 'WARN_ON_ONCE' 144 | int __ret_warn_once = !!(condition); \ | ^~~~~~~~~ arch/m68k/include/asm/page_mm.h:170:25: note: in expansion of macro 'virt_addr_valid' 170 | #define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn)) | ^~~~~~~~~~~~~~~ include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid' 352 | if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr)))) | ^~~~~~~~~ In file included from <command-line>: drivers/ide/gayle.c: At top level: >> arch/m68k/include/asm/amigayle.h:57:66: error: pasting ")" and "__279_185_amiga_gayle_ide_driver_init" does not give a valid preprocessing token 57 | #define gayle (*(volatile struct GAYLE *)(zTwoBase+GAYLE_ADDRESS)) | ^ include/linux/compiler_types.h:53:23: note: in definition of macro '___PASTE' 53 | #define ___PASTE(a,b) a##b | ^ >> include/linux/init.h:189:2: note: in expansion of macro '__PASTE' 189 | __PASTE(__KBUILD_MODNAME, \ | ^~~~~~~ >> <command-line>: note: in expansion of macro 'gayle' >> include/linux/init.h:189:10: note: in expansion of macro '__KBUILD_MODNAME' 189 | __PASTE(__KBUILD_MODNAME, \ | ^~~~~~~~~~~~~~~~ >> include/linux/init.h:236:35: note: in expansion of macro '__initcall_id' 236 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~ include/linux/init.h:238:35: note: in expansion of macro '___define_initcall' 238 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:267:30: note: in expansion of macro '__define_initcall' 267 | #define device_initcall(fn) __define_initcall(fn, 6) | ^~~~~~~~~~~~~~~~~ >> include/linux/init.h:272:24: note: in expansion of macro 'device_initcall' 272 | #define __initcall(fn) device_initcall(fn) | ^~~~~~~~~~~~~~~ >> include/linux/module.h:88:24: note: in expansion of macro '__initcall' 88 | #define module_init(x) __initcall(x); | ^~~~~~~~~~ include/linux/platform_device.h:271:1: note: in expansion of macro 'module_init' 271 | module_init(__platform_driver##_init); \ | ^~~~~~~~~~~ drivers/ide/gayle.c:185:1: note: in expansion of macro 'module_platform_driver_probe' 185 | module_platform_driver_probe(amiga_gayle_ide_driver, amiga_gayle_ide_probe); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> include/linux/init.h:200:10: error: pasting "__" and "(" does not give a valid preprocessing token 200 | __PASTE(__, \ | ^~ include/linux/compiler_types.h:53:23: note: in definition of macro '___PASTE' 53 | #define ___PASTE(a,b) a##b | ^ include/linux/init.h:200:2: note: in expansion of macro '__PASTE' 200 | __PASTE(__, \ | ^~~~~~~ >> include/linux/init.h:232:3: note: in expansion of macro '__initcall_name' 232 | __initcall_name(initcall, __iid, id), \ | ^~~~~~~~~~~~~~~ >> include/linux/init.h:236:2: note: in expansion of macro '__unique_initcall' 236 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:238:35: note: in expansion of macro '___define_initcall' 238 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:267:30: note: in expansion of macro '__define_initcall' 267 | #define device_initcall(fn) __define_initcall(fn, 6) | ^~~~~~~~~~~~~~~~~ >> include/linux/init.h:272:24: note: in expansion of macro 'device_initcall' 272 | #define __initcall(fn) device_initcall(fn) | ^~~~~~~~~~~~~~~ >> include/linux/module.h:88:24: note: in expansion of macro '__initcall' 88 | #define module_init(x) __initcall(x); | ^~~~~~~~~~ include/linux/platform_device.h:271:1: note: in expansion of macro 'module_init' 271 | module_init(__platform_driver##_init); \ | ^~~~~~~~~~~ drivers/ide/gayle.c:185:1: note: in expansion of macro 'module_platform_driver_probe' 185 | module_platform_driver_probe(amiga_gayle_ide_driver, amiga_gayle_ide_probe); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from include/linux/printk.h:6, from include/linux/kernel.h:15, from include/asm-generic/bug.h:19, from arch/m68k/include/asm/bug.h:32, from include/linux/bug.h:5, from include/linux/mmdebug.h:5, from include/linux/mm.h:9, from drivers/ide/gayle.c:12: >> arch/m68k/include/asm/amigayle.h:57:16: error: expected declaration specifiers or '...' before '*' token 57 | #define gayle (*(volatile struct GAYLE *)(zTwoBase+GAYLE_ADDRESS)) | ^ include/linux/init.h:226:20: note: in definition of macro '____define_initcall' 226 | static initcall_t __name __used \ | ^~~~~~ include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE' 54 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:198:2: note: in expansion of macro '__PASTE' 198 | __PASTE(__, \ | ^~~~~~~ include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE' 54 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:199:2: note: in expansion of macro '__PASTE' 199 | __PASTE(prefix, \ | ^~~~~~~ include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE' 54 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:200:2: note: in expansion of macro '__PASTE' 200 | __PASTE(__, \ | ^~~~~~~ include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE' 54 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:201:2: note: in expansion of macro '__PASTE' 201 | __PASTE(__iid, id)))) | ^~~~~~~ >> include/linux/init.h:232:3: note: in expansion of macro '__initcall_name' 232 | __initcall_name(initcall, __iid, id), \ | ^~~~~~~~~~~~~~~ >> include/linux/init.h:236:2: note: in expansion of macro '__unique_initcall' 236 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE' 54 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ >> include/linux/init.h:189:2: note: in expansion of macro '__PASTE' 189 | __PASTE(__KBUILD_MODNAME, \ | ^~~~~~~ >> <command-line>: note: in expansion of macro 'gayle' >> include/linux/init.h:189:10: note: in expansion of macro '__KBUILD_MODNAME' 189 | __PASTE(__KBUILD_MODNAME, \ | ^~~~~~~~~~~~~~~~ >> include/linux/init.h:236:35: note: in expansion of macro '__initcall_id' 236 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~ include/linux/init.h:238:35: note: in expansion of macro '___define_initcall' 238 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:267:30: note: in expansion of macro '__define_initcall' 267 | #define device_initcall(fn) __define_initcall(fn, 6) | ^~~~~~~~~~~~~~~~~ >> include/linux/init.h:272:24: note: in expansion of macro 'device_initcall' 272 | #define __initcall(fn) device_initcall(fn) | ^~~~~~~~~~~~~~~ include/linux/module.h:88:24: note: in expansion of macro '__initcall' 88 | #define module_init(x) __initcall(x); | ^~~~~~~~~~ include/linux/platform_device.h:271:1: note: in expansion of macro 'module_init' 271 | module_init(__platform_driver##_init); \ | ^~~~~~~~~~~ drivers/ide/gayle.c:185:1: note: in expansion of macro 'module_platform_driver_probe' 185 | module_platform_driver_probe(amiga_gayle_ide_driver, amiga_gayle_ide_probe); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/ide/gayle.c:19: drivers/ide/gayle.c:185:30: warning: 'amiga_gayle_ide_driver_init' defined but not used [-Wunused-function] 185 | module_platform_driver_probe(amiga_gayle_ide_driver, amiga_gayle_ide_probe); | ^~~~~~~~~~~~~~~~~~~~~~ include/linux/platform_device.h:266:19: note: in definition of macro 'module_platform_driver_probe' 266 | static int __init __platform_driver##_init(void) \ | ^~~~~~~~~~~~~~~~~ vim +200 include/linux/init.h 170 171 /* 172 * initcalls are now grouped by functionality into separate 173 * subsections. Ordering inside the subsections is determined 174 * by link order. 175 * For backwards compatibility, initcall() puts the call in 176 * the device init subsection. 177 * 178 * The `id' arg to __define_initcall() is needed so that multiple initcalls 179 * can point at the same handler without causing duplicate-symbol build errors. 180 * 181 * Initcalls are run by placing pointers in initcall sections that the 182 * kernel iterates at runtime. The linker can do dead code / data elimination 183 * and remove that completely, so the initcall sections have to be marked 184 * as KEEP() in the linker script. 185 */ 186 187 /* Format: <modname>__<counter>_<line>_<fn> */ 188 #define __initcall_id(fn) \ > 189 __PASTE(__KBUILD_MODNAME, \ 190 __PASTE(__, \ 191 __PASTE(__COUNTER__, \ 192 __PASTE(_, \ 193 __PASTE(__LINE__, \ 194 __PASTE(_, fn)))))) 195 196 /* Format: __<prefix>__<iid><id> */ 197 #define __initcall_name(prefix, __iid, id) \ 198 __PASTE(__, \ 199 __PASTE(prefix, \ > 200 __PASTE(__, \ 201 __PASTE(__iid, id)))) 202 203 #ifdef CONFIG_LTO_CLANG 204 /* 205 * With LTO, the compiler doesn't necessarily obey link order for 206 * initcalls. In order to preserve the correct order, we add each 207 * variable into its own section and generate a linker script (in 208 * scripts/link-vmlinux.sh) to specify the order of the sections. 209 */ 210 #define __initcall_section(__sec, __iid) \ 211 #__sec ".init.." #__iid 212 #else 213 #define __initcall_section(__sec, __iid) \ 214 #__sec ".init" 215 #endif 216 217 #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS 218 #define ____define_initcall(fn, __name, __sec) \ 219 __ADDRESSABLE(fn) \ 220 asm(".section \"" __sec "\", \"a\" \n" \ 221 __stringify(__name) ": \n" \ 222 ".long " #fn " - . \n" \ 223 ".previous \n"); 224 #else 225 #define ____define_initcall(fn, __name, __sec) \ 226 static initcall_t __name __used \ 227 __attribute__((__section__(__sec))) = fn; 228 #endif 229 230 #define __unique_initcall(fn, id, __sec, __iid) \ 231 ____define_initcall(fn, \ > 232 __initcall_name(initcall, __iid, id), \ 233 __initcall_section(__sec, __iid)) 234 235 #define ___define_initcall(fn, id, __sec) \ > 236 __unique_initcall(fn, id, __sec, __initcall_id(fn)) 237 238 #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) 239 240 /* 241 * Early initcalls run before initializing SMP. 242 * 243 * Only for built-in code, not modules. 244 */ 245 #define early_initcall(fn) __define_initcall(fn, early) 246 247 /* 248 * A "pure" initcall has no dependencies on anything else, and purely 249 * initializes variables that couldn't be statically initialized. 250 * 251 * This only exists for built-in code, not for modules. 252 * Keep main.c:initcall_level_names[] in sync. 253 */ 254 #define pure_initcall(fn) __define_initcall(fn, 0) 255 256 #define core_initcall(fn) __define_initcall(fn, 1) 257 #define core_initcall_sync(fn) __define_initcall(fn, 1s) 258 #define postcore_initcall(fn) __define_initcall(fn, 2) 259 #define postcore_initcall_sync(fn) __define_initcall(fn, 2s) 260 #define arch_initcall(fn) __define_initcall(fn, 3) 261 #define arch_initcall_sync(fn) __define_initcall(fn, 3s) 262 #define subsys_initcall(fn) __define_initcall(fn, 4) 263 #define subsys_initcall_sync(fn) __define_initcall(fn, 4s) 264 #define fs_initcall(fn) __define_initcall(fn, 5) 265 #define fs_initcall_sync(fn) __define_initcall(fn, 5s) 266 #define rootfs_initcall(fn) __define_initcall(fn, rootfs) 267 #define device_initcall(fn) __define_initcall(fn, 6) 268 #define device_initcall_sync(fn) __define_initcall(fn, 6s) 269 #define late_initcall(fn) __define_initcall(fn, 7) 270 #define late_initcall_sync(fn) __define_initcall(fn, 7s) 271 > 272 #define __initcall(fn) device_initcall(fn) 273 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Sami,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on 26e122e97a3d0390ebec389347f64f3730fdf48f]
url: https://github.com/0day-ci/linux/commits/Sami-Tolvanen/add-support-for-Clang-LTO/20200625-043816
base: 26e122e97a3d0390ebec389347f64f3730fdf48f
config: m68k-allyesconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=m68k
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
In file included from arch/m68k/include/asm/io_mm.h:25,
from arch/m68k/include/asm/io.h:8,
from include/linux/io.h:13,
from include/linux/irq.h:20,
from include/asm-generic/hardirq.h:13,
from ./arch/m68k/include/generated/asm/hardirq.h:1,
from include/linux/hardirq.h:10,
from include/linux/interrupt.h:11,
from drivers/ide/gayle.c:13:
arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsb':
arch/m68k/include/asm/raw_io.h:83:7: warning: variable '__w' set but not used [-Wunused-but-set-variable]
83 | ({u8 __w, __v = (b); u32 _addr = ((u32) (addr)); \
| ^~~
arch/m68k/include/asm/raw_io.h:430:3: note: in expansion of macro 'rom_out_8'
430 | rom_out_8(port, *buf++);
| ^~~~~~~~~
arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsw':
arch/m68k/include/asm/raw_io.h:86:8: warning: variable '__w' set but not used [-Wunused-but-set-variable]
86 | ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
| ^~~
arch/m68k/include/asm/raw_io.h:448:3: note: in expansion of macro 'rom_out_be16'
448 | rom_out_be16(port, *buf++);
| ^~~~~~~~~~~~
arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsw_swapw':
arch/m68k/include/asm/raw_io.h:90:8: warning: variable '__w' set but not used [-Wunused-but-set-variable]
90 | ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
| ^~~
arch/m68k/include/asm/raw_io.h:466:3: note: in expansion of macro 'rom_out_le16'
466 | rom_out_le16(port, *buf++);
| ^~~~~~~~~~~~
In file included from include/asm-generic/bug.h:5,
from arch/m68k/include/asm/bug.h:32,
from include/linux/bug.h:5,
from include/linux/mmdebug.h:5,
from include/linux/mm.h:9,
from drivers/ide/gayle.c:12:
include/linux/scatterlist.h: In function 'sg_set_buf':
arch/m68k/include/asm/page_mm.h:169:49: warning: ordered comparison of pointer with null pointer [-Wextra]
169 | #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
| ^~
include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
78 | # define unlikely(x) __builtin_expect(!!(x), 0)
| ^
include/linux/scatterlist.h:143:2: note: in expansion of macro 'BUG_ON'
143 | BUG_ON(!virt_addr_valid(buf));
| ^~~~~~
include/linux/scatterlist.h:143:10: note: in expansion of macro 'virt_addr_valid'
143 | BUG_ON(!virt_addr_valid(buf));
| ^~~~~~~~~~~~~~~
In file included from arch/m68k/include/asm/bug.h:32,
from include/linux/bug.h:5,
from include/linux/mmdebug.h:5,
from include/linux/mm.h:9,
from drivers/ide/gayle.c:12:
include/linux/dma-mapping.h: In function 'dma_map_resource':
arch/m68k/include/asm/page_mm.h:169:49: warning: ordered comparison of pointer with null pointer [-Wextra]
169 | #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
| ^~
include/asm-generic/bug.h:144:27: note: in definition of macro 'WARN_ON_ONCE'
144 | int __ret_warn_once = !!(condition); \
| ^~~~~~~~~
arch/m68k/include/asm/page_mm.h:170:25: note: in expansion of macro 'virt_addr_valid'
170 | #define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
| ^~~~~~~~~~~~~~~
include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
352 | if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
| ^~~~~~~~~
In file included from <command-line>:
drivers/ide/gayle.c: At top level:
>> arch/m68k/include/asm/amigayle.h:57:66: error: pasting ")" and "__282_185_amiga_gayle_ide_driver_init" does not give a valid preprocessing token
57 | #define gayle (*(volatile struct GAYLE *)(zTwoBase+GAYLE_ADDRESS))
| ^
include/linux/compiler_types.h:53:23: note: in definition of macro '___PASTE'
53 | #define ___PASTE(a,b) a##b
| ^
include/linux/init.h:189:2: note: in expansion of macro '__PASTE'
189 | __PASTE(__KBUILD_MODNAME, \
| ^~~~~~~
<command-line>: note: in expansion of macro 'gayle'
include/linux/init.h:189:10: note: in expansion of macro '__KBUILD_MODNAME'
189 | __PASTE(__KBUILD_MODNAME, \
| ^~~~~~~~~~~~~~~~
include/linux/init.h:236:35: note: in expansion of macro '__initcall_id'
236 | __unique_initcall(fn, id, __sec, __initcall_id(fn))
| ^~~~~~~~~~~~~
include/linux/init.h:238:35: note: in expansion of macro '___define_initcall'
238 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id)
| ^~~~~~~~~~~~~~~~~~
include/linux/init.h:267:30: note: in expansion of macro '__define_initcall'
267 | #define device_initcall(fn) __define_initcall(fn, 6)
| ^~~~~~~~~~~~~~~~~
include/linux/init.h:272:24: note: in expansion of macro 'device_initcall'
272 | #define __initcall(fn) device_initcall(fn)
| ^~~~~~~~~~~~~~~
include/linux/module.h:88:24: note: in expansion of macro '__initcall'
88 | #define module_init(x) __initcall(x);
| ^~~~~~~~~~
include/linux/platform_device.h:271:1: note: in expansion of macro 'module_init'
271 | module_init(__platform_driver##_init); \
| ^~~~~~~~~~~
drivers/ide/gayle.c:185:1: note: in expansion of macro 'module_platform_driver_probe'
185 | module_platform_driver_probe(amiga_gayle_ide_driver, amiga_gayle_ide_probe);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/init.h:200:10: error: pasting "__" and "(" does not give a valid preprocessing token
200 | __PASTE(__, \
| ^~
include/linux/compiler_types.h:53:23: note: in definition of macro '___PASTE'
53 | #define ___PASTE(a,b) a##b
| ^
include/linux/init.h:200:2: note: in expansion of macro '__PASTE'
200 | __PASTE(__, \
| ^~~~~~~
include/linux/init.h:232:3: note: in expansion of macro '__initcall_name'
232 | __initcall_name(initcall, __iid, id), \
| ^~~~~~~~~~~~~~~
include/linux/init.h:236:2: note: in expansion of macro '__unique_initcall'
236 | __unique_initcall(fn, id, __sec, __initcall_id(fn))
| ^~~~~~~~~~~~~~~~~
include/linux/init.h:238:35: note: in expansion of macro '___define_initcall'
238 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id)
| ^~~~~~~~~~~~~~~~~~
include/linux/init.h:267:30: note: in expansion of macro '__define_initcall'
267 | #define device_initcall(fn) __define_initcall(fn, 6)
| ^~~~~~~~~~~~~~~~~
include/linux/init.h:272:24: note: in expansion of macro 'device_initcall'
272 | #define __initcall(fn) device_initcall(fn)
| ^~~~~~~~~~~~~~~
include/linux/module.h:88:24: note: in expansion of macro '__initcall'
88 | #define module_init(x) __initcall(x);
| ^~~~~~~~~~
include/linux/platform_device.h:271:1: note: in expansion of macro 'module_init'
271 | module_init(__platform_driver##_init); \
| ^~~~~~~~~~~
drivers/ide/gayle.c:185:1: note: in expansion of macro 'module_platform_driver_probe'
185 | module_platform_driver_probe(amiga_gayle_ide_driver, amiga_gayle_ide_probe);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from include/linux/printk.h:6,
from include/linux/kernel.h:15,
from include/asm-generic/bug.h:19,
from arch/m68k/include/asm/bug.h:32,
from include/linux/bug.h:5,
from include/linux/mmdebug.h:5,
from include/linux/mm.h:9,
from drivers/ide/gayle.c:12:
arch/m68k/include/asm/amigayle.h:57:16: error: expected declaration specifiers or '...' before '*' token
57 | #define gayle (*(volatile struct GAYLE *)(zTwoBase+GAYLE_ADDRESS))
| ^
include/linux/init.h:226:20: note: in definition of macro '____define_initcall'
226 | static initcall_t __name __used \
| ^~~~~~
include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE'
54 | #define __PASTE(a,b) ___PASTE(a,b)
| ^~~~~~~~
include/linux/init.h:198:2: note: in expansion of macro '__PASTE'
198 | __PASTE(__, \
| ^~~~~~~
include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE'
54 | #define __PASTE(a,b) ___PASTE(a,b)
| ^~~~~~~~
include/linux/init.h:199:2: note: in expansion of macro '__PASTE'
199 | __PASTE(prefix, \
| ^~~~~~~
include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE'
54 | #define __PASTE(a,b) ___PASTE(a,b)
| ^~~~~~~~
include/linux/init.h:200:2: note: in expansion of macro '__PASTE'
200 | __PASTE(__, \
| ^~~~~~~
include/linux/compiler_types.h:54:22: note: in expansion of macro '___PASTE'
54 | #define __PASTE(a,b) ___PASTE(a,b)
vim +57 arch/m68k/include/asm/amigayle.h
^1da177e4c3f41 include/asm-m68k/amigayle.h Linus Torvalds 2005-04-16 53
^1da177e4c3f41 include/asm-m68k/amigayle.h Linus Torvalds 2005-04-16 54 #define GAYLE_RESET (0xa40000) /* write 0x00 to start reset,
^1da177e4c3f41 include/asm-m68k/amigayle.h Linus Torvalds 2005-04-16 55 read 1 byte to stop reset */
^1da177e4c3f41 include/asm-m68k/amigayle.h Linus Torvalds 2005-04-16 56
^1da177e4c3f41 include/asm-m68k/amigayle.h Linus Torvalds 2005-04-16 @57 #define gayle (*(volatile struct GAYLE *)(zTwoBase+GAYLE_ADDRESS))
^1da177e4c3f41 include/asm-m68k/amigayle.h Linus Torvalds 2005-04-16 58 #define gayle_reset (*(volatile u_char *)(zTwoBase+GAYLE_RESET))
^1da177e4c3f41 include/asm-m68k/amigayle.h Linus Torvalds 2005-04-16 59
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/include/linux/init.h b/include/linux/init.h index 212fc9e2f691..af638cd6dd52 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -184,19 +184,57 @@ extern bool initcall_debug; * as KEEP() in the linker script. */ +/* Format: <modname>__<counter>_<line>_<fn> */ +#define __initcall_id(fn) \ + __PASTE(__KBUILD_MODNAME, \ + __PASTE(__, \ + __PASTE(__COUNTER__, \ + __PASTE(_, \ + __PASTE(__LINE__, \ + __PASTE(_, fn)))))) + +/* Format: __<prefix>__<iid><id> */ +#define __initcall_name(prefix, __iid, id) \ + __PASTE(__, \ + __PASTE(prefix, \ + __PASTE(__, \ + __PASTE(__iid, id)))) + +#ifdef CONFIG_LTO_CLANG +/* + * With LTO, the compiler doesn't necessarily obey link order for + * initcalls. In order to preserve the correct order, we add each + * variable into its own section and generate a linker script (in + * scripts/link-vmlinux.sh) to specify the order of the sections. + */ +#define __initcall_section(__sec, __iid) \ + #__sec ".init.." #__iid +#else +#define __initcall_section(__sec, __iid) \ + #__sec ".init" +#endif + #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS -#define ___define_initcall(fn, id, __sec) \ +#define ____define_initcall(fn, __name, __sec) \ __ADDRESSABLE(fn) \ - asm(".section \"" #__sec ".init\", \"a\" \n" \ - "__initcall_" #fn #id ": \n" \ + asm(".section \"" __sec "\", \"a\" \n" \ + __stringify(__name) ": \n" \ ".long " #fn " - . \n" \ ".previous \n"); #else -#define ___define_initcall(fn, id, __sec) \ - static initcall_t __initcall_##fn##id __used \ - __attribute__((__section__(#__sec ".init"))) = fn; +#define ____define_initcall(fn, __name, __sec) \ + static initcall_t __name __used \ + __attribute__((__section__(__sec))) = fn; #endif +#define __unique_initcall(fn, id, __sec, __iid) \ + ____define_initcall(fn, \ + __initcall_name(initcall, __iid, id), \ + __initcall_section(__sec, __iid)) + +#define ___define_initcall(fn, id, __sec) \ + __unique_initcall(fn, id, __sec, __initcall_id(fn)) + #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) /* @@ -236,7 +274,7 @@ extern bool initcall_debug; #define __exitcall(fn) \ static exitcall_t __exitcall_##fn __exit_call = fn -#define console_initcall(fn) ___define_initcall(fn,, .con_initcall) +#define console_initcall(fn) ___define_initcall(fn, con, .con_initcall) struct obs_kernel_param { const char *str; diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 99ac59c59826..17447354b543 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -106,9 +106,11 @@ target-stem = $(basename $(patsubst $(obj)/%,%,$@)) # These flags are needed for modversions and compiling, so we define them here # $(modname_flags) defines KBUILD_MODNAME as the name of the module it will # end up in (or would, if it gets compiled in) -name-fix = $(call stringify,$(subst $(comma),_,$(subst -,_,$1))) +name-fix-token = $(subst $(comma),_,$(subst -,_,$1)) +name-fix = $(call stringify,$(call name-fix-token,$1)) basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) -modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) +modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \ + -D__KBUILD_MODNAME=$(call name-fix-token,$(modname)) modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile)) orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ diff --git a/scripts/generate_initcall_order.pl b/scripts/generate_initcall_order.pl new file mode 100755 index 000000000000..fe83aec2b51e --- /dev/null +++ b/scripts/generate_initcall_order.pl @@ -0,0 +1,270 @@ +#!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +# +# Generates a linker script that specifies the correct initcall order. +# +# Copyright (C) 2019 Google LLC + +use strict; +use warnings; +use IO::Handle; +use IO::Select; +use POSIX ":sys_wait_h"; + +my $nm = $ENV{'NM'} || die "$0: ERROR: NM not set?"; +my $objtree = $ENV{'objtree'} || '.'; + +## currently active child processes +my $jobs = {}; # child process pid -> file handle +## results from child processes +my $results = {}; # object index -> [ { level, secname }, ... ] + +## reads _NPROCESSORS_ONLN to determine the maximum number of processes to +## start +sub get_online_processors { + open(my $fh, "getconf _NPROCESSORS_ONLN 2>/dev/null |") + or die "$0: ERROR: failed to execute getconf: $!"; + my $procs = <$fh>; + close($fh); + + if (!($procs =~ /^\d+$/)) { + return 1; + } + + return int($procs); +} + +## writes results to the parent process +## format: <file index> <initcall level> <base initcall section name> +sub write_results { + my ($index, $initcalls) = @_; + + # sort by the counter value to ensure the order of initcalls within + # each object file is correct + foreach my $counter (sort { $a <=> $b } keys(%{$initcalls})) { + my $level = $initcalls->{$counter}->{'level'}; + + # section name for the initcall function + my $secname = $initcalls->{$counter}->{'module'} . '__' . + $counter . '_' . + $initcalls->{$counter}->{'line'} . '_' . + $initcalls->{$counter}->{'function'}; + + print "$index $level $secname\n"; + } +} + +## reads a result line from a child process and adds it to the $results array +sub read_results{ + my ($fh) = @_; + + # each child prints out a full line w/ autoflush and exits after the + # last line, so even if buffered I/O blocks here, it shouldn't block + # very long + my $data = <$fh>; + + if (!defined($data)) { + return 0; + } + + chomp($data); + + my ($index, $level, $secname) = $data =~ + /^(\d+)\ ([^\ ]+)\ (.*)$/; + + if (!defined($index) || + !defined($level) || + !defined($secname)) { + die "$0: ERROR: child process returned invalid data: $data\n"; + } + + $index = int($index); + + if (!exists($results->{$index})) { + $results->{$index} = []; + } + + push (@{$results->{$index}}, { + 'level' => $level, + 'secname' => $secname + }); + + return 1; +} + +## finds initcalls from an object file or all object files in an archive, and +## writes results back to the parent process +sub find_initcalls { + my ($index, $file) = @_; + + die "$0: ERROR: file $file doesn't exist?" if (! -f $file); + + open(my $fh, "\"$nm\" --defined-only \"$file\" 2>/dev/null |") + or die "$0: ERROR: failed to execute \"$nm\": $!"; + + my $initcalls = {}; + + while (<$fh>) { + chomp; + + # check for the start of a new object file (if processing an + # archive) + my ($path)= $_ =~ /^(.+)\:$/; + + if (defined($path)) { + write_results($index, $initcalls); + $initcalls = {}; + next; + } + + # look for an initcall + my ($module, $counter, $line, $symbol) = $_ =~ + /[a-z]\s+__initcall__(\S*)__(\d+)_(\d+)_(.*)$/; + + if (!defined($module)) { + $module = '' + } + + if (!defined($counter) || + !defined($line) || + !defined($symbol)) { + next; + } + + # parse initcall level + my ($function, $level) = $symbol =~ + /^(.*)((early|rootfs|con|[0-9])s?)$/; + + die "$0: ERROR: invalid initcall name $symbol in $file($path)" + if (!defined($function) || !defined($level)); + + $initcalls->{$counter} = { + 'module' => $module, + 'line' => $line, + 'function' => $function, + 'level' => $level, + }; + } + + close($fh); + write_results($index, $initcalls); +} + +## waits for any child process to complete, reads the results, and adds them to +## the $results array for later processing +sub wait_for_results { + my ($select) = @_; + + my $pid = 0; + do { + # unblock children that may have a full write buffer + foreach my $fh ($select->can_read(0)) { + read_results($fh); + } + + # check for children that have exited, read the remaining data + # from them, and clean up + $pid = waitpid(-1, WNOHANG); + if ($pid > 0) { + if (!exists($jobs->{$pid})) { + next; + } + + my $fh = $jobs->{$pid}; + $select->remove($fh); + + while (read_results($fh)) { + # until eof + } + + close($fh); + delete($jobs->{$pid}); + } + } while ($pid > 0); +} + +## forks a child to process each file passed in the command line and collects +## the results +sub process_files { + my $index = 0; + my $njobs = get_online_processors(); + my $select = IO::Select->new(); + + while (my $file = shift(@ARGV)) { + # fork a child process and read it's stdout + my $pid = open(my $fh, '-|'); + + if (!defined($pid)) { + die "$0: ERROR: failed to fork: $!"; + } elsif ($pid) { + # save the child process pid and the file handle + $select->add($fh); + $jobs->{$pid} = $fh; + } else { + # in the child process + STDOUT->autoflush(1); + find_initcalls($index, "$objtree/$file"); + exit; + } + + $index++; + + # limit the number of children to $njobs + if (scalar(keys(%{$jobs})) >= $njobs) { + wait_for_results($select); + } + } + + # wait for the remaining children to complete + while (scalar(keys(%{$jobs})) > 0) { + wait_for_results($select); + } +} + +sub generate_initcall_lds() { + process_files(); + + my $sections = {}; # level -> [ secname, ...] + + # sort results to retain link order and split to sections per + # initcall level + foreach my $index (sort { $a <=> $b } keys(%{$results})) { + foreach my $result (@{$results->{$index}}) { + my $level = $result->{'level'}; + + if (!exists($sections->{$level})) { + $sections->{$level} = []; + } + + push(@{$sections->{$level}}, $result->{'secname'}); + } + } + + die "$0: ERROR: no initcalls?" if (!keys(%{$sections})); + + # print out a linker script that defines the order of initcalls for + # each level + print "SECTIONS {\n"; + + foreach my $level (sort(keys(%{$sections}))) { + my $section; + + if ($level eq 'con') { + $section = '.con_initcall.init'; + } else { + $section = ".initcall${level}.init"; + } + + print "\t${section} : {\n"; + + foreach my $secname (@{$sections->{$level}}) { + print "\t\t*(${section}..${secname}) ;\n"; + } + + print "\t}\n"; + } + + print "}\n"; +} + +generate_initcall_lds(); diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index c72f5d0238f1..42c73e24e820 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -39,6 +39,16 @@ info() fi } +# Generate a linker script to ensure correct ordering of initcalls. +gen_initcalls() +{ + info GEN .tmp_initcalls.lds + + ${srctree}/scripts/generate_initcall_order.pl \ + ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS} \ + > .tmp_initcalls.lds +} + # If CONFIG_LTO_CLANG is selected, collect generated symbol versions into # .tmp_symversions.lds gen_symversions() @@ -70,6 +80,9 @@ modpost_link() --end-group" if [ -n "${CONFIG_LTO_CLANG}" ]; then + gen_initcalls + lds="-T .tmp_initcalls.lds" + if [ -n "${CONFIG_MODVERSIONS}" ]; then gen_symversions lds="${lds} -T .tmp_symversions.lds" @@ -283,6 +296,7 @@ cleanup() { rm -f .btf.* rm -f .tmp_System.map + rm -f .tmp_initcalls.lds rm -f .tmp_symversions.lds rm -f .tmp_vmlinux* rm -f System.map
With LTO, the compiler doesn't necessarily obey the link order for initcalls, and initcall variables need globally unique names to avoid collisions at link time. This change exports __KBUILD_MODNAME and adds the initcall_id() macro, which uses it together with __COUNTER__ and __LINE__ to help ensure these variables have unique names, and moves each variable to its own section when LTO is enabled, so the correct order can be specified using a linker script. The generate_initcall_ordering.pl script uses nm to find initcalls from the object files passed to the linker, and generates a linker script that specifies the intended order. With LTO, the script is called in link-vmlinux.sh. Signed-off-by: Sami Tolvanen <samitolvanen@google.com> --- include/linux/init.h | 52 +++++- scripts/Makefile.lib | 6 +- scripts/generate_initcall_order.pl | 270 +++++++++++++++++++++++++++++ scripts/link-vmlinux.sh | 14 ++ 4 files changed, 333 insertions(+), 9 deletions(-) create mode 100755 scripts/generate_initcall_order.pl