From ba64beb17493a4bfec563100c86a462a15926f24 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 16 Mar 2021 01:12:56 +0900 Subject: kbuild: check the minimum assembler version in Kconfig Documentation/process/changes.rst defines the minimum assembler version (binutils version), but we have never checked it in the build time. Kbuild never invokes 'as' directly because all assembly files in the kernel tree are *.S, hence must be preprocessed. I do not expect raw assembly source files (*.s) would be added to the kernel tree. Therefore, we always use $(CC) as the assembler driver, and commit aa824e0c962b ("kbuild: remove AS variable") removed 'AS'. However, we are still interested in the version of the assembler acting behind. As usual, the --version option prints the version string. $ as --version | head -n 1 GNU assembler (GNU Binutils for Ubuntu) 2.35.1 But, we do not have $(AS). So, we can add the -Wa prefix so that $(CC) passes --version down to the backing assembler. $ gcc -Wa,--version | head -n 1 gcc: fatal error: no input files compilation terminated. OK, we need to input something to satisfy gcc. $ gcc -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 GNU assembler (GNU Binutils for Ubuntu) 2.35.1 The combination of Clang and GNU assembler works in the same way: $ clang -no-integrated-as -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 GNU assembler (GNU Binutils for Ubuntu) 2.35.1 Clang with the integrated assembler fails like this: $ clang -integrated-as -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 clang: error: unsupported argument '--version' to option 'Wa,' For the last case, checking the error message is fragile. If the proposal for -Wa,--version support [1] is accepted, this may not be even an error in the future. One easy way is to check if -integrated-as is present in the passed arguments. We did not pass -integrated-as to CLANG_FLAGS before, but we can make it explicit. Nathan pointed out -integrated-as is the default for all of the architectures/targets that the kernel cares about, but it goes along with "explicit is better than implicit" policy. [2] With all this in my mind, I implemented scripts/as-version.sh to check the assembler version in Kconfig time. $ scripts/as-version.sh gcc GNU 23501 $ scripts/as-version.sh clang -no-integrated-as GNU 23501 $ scripts/as-version.sh clang -integrated-as LLVM 0 [1]: https://github.com/ClangBuiltLinux/linux/issues/1320 [2]: https://lore.kernel.org/linux-kbuild/20210307044253.v3h47ucq6ng25iay@archlinux-ax161/ Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor --- init/Kconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'init') diff --git a/init/Kconfig b/init/Kconfig index 5f5c776ef192..019c1874e609 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -41,6 +41,18 @@ config CLANG_VERSION default $(cc-version) if CC_IS_CLANG default 0 +config AS_IS_GNU + def_bool $(success,test "$(as-name)" = GNU) + +config AS_IS_LLVM + def_bool $(success,test "$(as-name)" = LLVM) + +config AS_VERSION + int + # Use clang version if this is the integrated assembler + default CLANG_VERSION if AS_IS_LLVM + default $(as-version) + config LD_IS_BFD def_bool $(success,test "$(ld-name)" = BFD) -- cgit v1.2.3 From d4bbe942098b0c9b487d424a3c545c9ed56462d7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 31 Mar 2021 22:38:10 +0900 Subject: kbuild: remove CONFIG_MODULE_COMPRESS CONFIG_MODULE_COMPRESS is only used to activate the choice for module compression algorithm. It will be simpler to make the choice always visible, and add CONFIG_MODULE_COMPRESS_NONE in the choice. This is more consistent with the "Kernel compression mode" and "Built-in initramfs compression mode" choices. CONFIG_KERNEL_UNCOMPRESSED and CONFIG_INITRAMFS_COMPRESSION_NONE are available to choose no compression. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- init/Kconfig | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'init') diff --git a/init/Kconfig b/init/Kconfig index 019c1874e609..510f6fcd9b7f 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2225,40 +2225,47 @@ config MODULE_SIG_HASH default "sha384" if MODULE_SIG_SHA384 default "sha512" if MODULE_SIG_SHA512 -config MODULE_COMPRESS - bool "Compress modules on installation" +choice + prompt "Module compression mode" help + This option allows you to choose the algorithm which will be used to + compress modules when 'make modules_install' is run. (or, you can + choose to not compress modules at all.) - Compresses kernel modules when 'make modules_install' is run; gzip or - xz depending on "Compression algorithm" below. + External modules will also be compressed in the same way during the + installation. - module-init-tools MAY support gzip, and kmod MAY support gzip and xz. + For modules inside an initrd or initramfs, it's more efficient to + compress the whole initrd or initramfs instead. - Out-of-tree kernel modules installed using Kbuild will also be - compressed upon installation. + This is fully compatible with signed modules. - Note: for modules inside an initrd or initramfs, it's more efficient - to compress the whole initrd or initramfs instead. + Please note that the tool used to load modules needs to support the + corresponding algorithm. module-init-tools MAY support gzip, and kmod + MAY support gzip and xz. - Note: This is fully compatible with signed modules. + Your build system needs to provide the appropriate compression tool + to compress the modules. - If in doubt, say N. + If in doubt, select 'None'. -choice - prompt "Compression algorithm" - depends on MODULE_COMPRESS - default MODULE_COMPRESS_GZIP +config MODULE_COMPRESS_NONE + bool "None" help - This determines which sort of compression will be used during - 'make modules_install'. - - GZIP (default) and XZ are supported. + Do not compress modules. The installed modules are suffixed + with .ko. config MODULE_COMPRESS_GZIP bool "GZIP" + help + Compress modules with GZIP. The installed modules are suffixed + with .ko.gz. config MODULE_COMPRESS_XZ bool "XZ" + help + Compress modules with XZ. The installed modules are suffixed + with .ko.xz. endchoice -- cgit v1.2.3 From c3d7ef377eb2564b165b1e8fdb4646952c90ac17 Mon Sep 17 00:00:00 2001 From: Piotr Gorski Date: Wed, 7 Apr 2021 18:09:27 +0200 Subject: kbuild: add support for zstd compressed modules kmod 28 supports modules compressed in zstd format so let's add this possibility to kernel. Signed-off-by: Piotr Gorski Reviewed-by: Oleksandr Natalenko Signed-off-by: Masahiro Yamada --- init/Kconfig | 8 +++++++- scripts/Makefile.modinst | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'init') diff --git a/init/Kconfig b/init/Kconfig index 510f6fcd9b7f..b5744d32c4df 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2242,7 +2242,7 @@ choice Please note that the tool used to load modules needs to support the corresponding algorithm. module-init-tools MAY support gzip, and kmod - MAY support gzip and xz. + MAY support gzip, xz and zstd. Your build system needs to provide the appropriate compression tool to compress the modules. @@ -2267,6 +2267,12 @@ config MODULE_COMPRESS_XZ Compress modules with XZ. The installed modules are suffixed with .ko.xz. +config MODULE_COMPRESS_ZSTD + bool "ZSTD" + help + Compress modules with ZSTD. The installed modules are suffixed + with .ko.zst. + endchoice config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 191408f7a91a..ff9b09e4cfca 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -21,6 +21,7 @@ endif suffix-y := suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz +suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst modules := $(patsubst $(extmod_prefix)%, $(dst)/%$(suffix-y), $(modules)) @@ -95,6 +96,8 @@ quiet_cmd_gzip = GZIP $@ cmd_gzip = $(KGZIP) -n -f $< quiet_cmd_xz = XZ $@ cmd_xz = $(XZ) --lzma2=dict=2MiB -f $< +quiet_cmd_zstd = ZSTD $@ + cmd_zstd = $(ZSTD) -T0 --rm -f -q $< $(dst)/%.ko.gz: $(dst)/%.ko FORCE $(call cmd,gzip) @@ -102,6 +105,9 @@ $(dst)/%.ko.gz: $(dst)/%.ko FORCE $(dst)/%.ko.xz: $(dst)/%.ko FORCE $(call cmd,xz) +$(dst)/%.ko.zst: $(dst)/%.ko FORCE + $(call cmd,zstd) + PHONY += FORCE FORCE: -- cgit v1.2.3 From 1fdd7433a98a2f5511f49ad3f3b82bdd6f77265c Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Thu, 1 Apr 2021 16:27:23 -0700 Subject: kbuild: add an elfnote for whether vmlinux is built with lto Currently, clang LTO built vmlinux won't work with pahole. LTO introduced cross-cu dwarf tag references and broke current pahole model which handles one cu as a time. The solution is to merge all cu's as one pahole cu as in [1]. We would like to do this merging only if cross-cu dwarf references happens. The LTO build mode is a pretty good indication for that. In earlier version of this patch ([2]), clang flag -grecord-gcc-switches is proposed to add to compilation flags so pahole could detect "-flto" and then merging cu's. This will increate the binary size of 1% without LTO though. Arnaldo suggested to use a note to indicate the vmlinux is built with LTO. Such a cheap way to get whether the vmlinux is built with LTO or not helps pahole but is also useful for tracing as LTO may inline/delete/demote global functions, promote static functions, etc. So this patch added an elfnote with a new type LINUX_ELFNOTE_LTO_INFO. The owner of the note is "Linux". With gcc 8.4.1 and clang trunk, without LTO, I got $ readelf -n vmlinux Displaying notes found in: .notes Owner Data size Description ... Linux 0x00000004 func description data: 00 00 00 00 ... With "readelf -x ".notes" vmlinux", I can verify the above "func" with type code 0x101. With clang thin-LTO, I got the same as above except the following: description data: 01 00 00 00 which indicates the vmlinux is built with LTO. [1] https://lore.kernel.org/bpf/20210325065316.3121287-1-yhs@fb.com/ [2] https://lore.kernel.org/bpf/20210331001623.2778934-1-yhs@fb.com/ Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Yonghong Song Reviewed-by: Nick Desaulniers Tested-by: Sedat Dilek # LLVM/Clang v12.0.0-rc4 (x86-64) Tested-by: Arnaldo Carvalho de Melo Signed-off-by: Masahiro Yamada --- include/linux/elfnote-lto.h | 14 ++++++++++++++ init/version.c | 2 ++ scripts/mod/modpost.c | 2 ++ 3 files changed, 18 insertions(+) create mode 100644 include/linux/elfnote-lto.h (limited to 'init') diff --git a/include/linux/elfnote-lto.h b/include/linux/elfnote-lto.h new file mode 100644 index 000000000000..d4635a3ecc4f --- /dev/null +++ b/include/linux/elfnote-lto.h @@ -0,0 +1,14 @@ +#ifndef __ELFNOTE_LTO_H +#define __ELFNOTE_LTO_H + +#include + +#define LINUX_ELFNOTE_LTO_INFO 0x101 + +#ifdef CONFIG_LTO +#define BUILD_LTO_INFO ELFNOTE32("Linux", LINUX_ELFNOTE_LTO_INFO, 1) +#else +#define BUILD_LTO_INFO ELFNOTE32("Linux", LINUX_ELFNOTE_LTO_INFO, 0) +#endif + +#endif /* __ELFNOTE_LTO_H */ diff --git a/init/version.c b/init/version.c index 92afc782b043..1a356f5493e8 100644 --- a/init/version.c +++ b/init/version.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -45,3 +46,4 @@ const char linux_proc_banner[] = " (" LINUX_COMPILER ") %s\n"; BUILD_SALT; +BUILD_LTO_INFO; diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 20aab6960559..3e623ccc020b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2193,10 +2193,12 @@ static void add_header(struct buffer *b, struct module *mod) */ buf_printf(b, "#define INCLUDE_VERMAGIC\n"); buf_printf(b, "#include \n"); + buf_printf(b, "#include \n"); buf_printf(b, "#include \n"); buf_printf(b, "#include \n"); buf_printf(b, "\n"); buf_printf(b, "BUILD_SALT;\n"); + buf_printf(b, "BUILD_LTO_INFO;\n"); buf_printf(b, "\n"); buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); -- cgit v1.2.3 From 0e0345b77ac4605d5447b252d220e4a2ee118da7 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 15 Apr 2021 20:36:07 +0300 Subject: kbuild: redo fake deps at include/config/*.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make include/config/foo/bar.h fake deps files generation simpler. * delete .h suffix those aren't header files, shorten filenames, * delete tolower() Linux filesystems can deal with both upper and lowercase filenames very well, * put everything in 1 directory Presumably 'mkdir -p' split is from dark times when filesystems handled huge directories badly, disks were round adding to seek times. x86_64 allmodconfig lists 12364 files in include/config. ../obj/include/config/ ├── 104_QUAD_8 ├── 60XX_WDT ├── 64BIT ... ├── ZSWAP_DEFAULT_ON ├── ZSWAP_ZPOOL_DEFAULT └── ZSWAP_ZPOOL_DEFAULT_ZBUD 0 directories, 12364 files Signed-off-by: Alexey Dobriyan Signed-off-by: Masahiro Yamada --- include/linux/compiler-version.h | 2 +- init/Kconfig | 2 +- kernel/gen_kheaders.sh | 2 +- scripts/Makefile.build | 4 ++-- scripts/basic/fixdep.c | 43 ++++++---------------------------------- scripts/kconfig/confdata.c | 15 +++++--------- 6 files changed, 16 insertions(+), 52 deletions(-) (limited to 'init') diff --git a/include/linux/compiler-version.h b/include/linux/compiler-version.h index 2b2972c77c62..573fa85b6c0c 100644 --- a/include/linux/compiler-version.h +++ b/include/linux/compiler-version.h @@ -9,6 +9,6 @@ * This header exists to force full rebuild when the compiler is upgraded. * * When fixdep scans this, it will find this string "CONFIG_CC_VERSION_TEXT" - * and add dependency on include/config/cc/version/text.h, which is touched + * and add dependency on include/config/CC_VERSION_TEXT, which is touched * by Kconfig when the version string from the compiler changes. */ diff --git a/init/Kconfig b/init/Kconfig index b5744d32c4df..c2339da03468 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -21,7 +21,7 @@ config CC_VERSION_TEXT - Ensure full rebuild when the compiler is updated include/linux/compiler-version.h contains this option in the comment - line so fixdep adds include/config/cc/version/text.h into the + line so fixdep adds include/config/CC_VERSION_TEXT into the auto-generated dependency. When the compiler is updated, syncconfig will touch it and then every file will be rebuilt. diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index c1510f0ab3ea..34a1dc2abc7d 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -36,7 +36,7 @@ all_dirs="$all_dirs $dir_list" # # When Kconfig regenerates include/generated/autoconf.h, its timestamp is # updated, but the contents might be still the same. When any CONFIG option is -# changed, Kconfig touches the corresponding timestamp file include/config/*.h. +# changed, Kconfig touches the corresponding timestamp file include/config/*. # Hence, the md5sum detects the configuration change anyway. We do not need to # check include/generated/autoconf.h explicitly. # diff --git a/scripts/Makefile.build b/scripts/Makefile.build index e47c054d3db2..5e39b0517186 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -239,8 +239,8 @@ endif # CONFIG_STACK_VALIDATION # Rebuild all objects when objtool changes, or is enabled/disabled. objtool_dep = $(objtool_obj) \ - $(wildcard include/config/orc/unwinder.h \ - include/config/stack/validation.h) + $(wildcard include/config/ORC_UNWINDER \ + include/config/STACK_VALIDATION) ifdef CONFIG_TRIM_UNUSED_KSYMS cmd_gen_ksymdeps = \ diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index d98540552941..44e887cff49b 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -34,7 +34,7 @@ * the config symbols are rebuilt. * * So if the user changes his CONFIG_HIS_DRIVER option, only the objects - * which depend on "include/config/his/driver.h" will be rebuilt, + * which depend on "include/config/HIS_DRIVER" will be rebuilt, * so most likely only his driver ;-) * * The idea above dates, by the way, back to Michael E Chastain, AFAIK. @@ -74,7 +74,7 @@ * * and then basically copies the ..d file to stdout, in the * process filtering out the dependency on autoconf.h and adding - * dependencies on include/config/my/option.h for every + * dependencies on include/config/MY_OPTION for every * CONFIG_MY_OPTION encountered in any of the prerequisites. * * We don't even try to really parse the header files, but @@ -107,8 +107,8 @@ static void usage(void) /* * In the intended usage of this program, the stdout is redirected to .*.cmd - * files. The return value of printf() and putchar() must be checked to catch - * any error, e.g. "No space left on device". + * files. The return value of printf() must be checked to catch any error, + * e.g. "No space left on device". */ static void xprintf(const char *format, ...) { @@ -124,38 +124,6 @@ static void xprintf(const char *format, ...) va_end(ap); } -static void xputchar(int c) -{ - int ret; - - ret = putchar(c); - if (ret == EOF) { - perror("fixdep"); - exit(1); - } -} - -/* - * Print out a dependency path from a symbol name - */ -static void print_dep(const char *m, int slen, const char *dir) -{ - int c, prev_c = '/', i; - - xprintf(" $(wildcard %s/", dir); - for (i = 0; i < slen; i++) { - c = m[i]; - if (c == '_') - c = '/'; - else - c = tolower(c); - if (c != '/' || prev_c != '/') - xputchar(c); - prev_c = c; - } - xprintf(".h) \\\n"); -} - struct item { struct item *next; unsigned int len; @@ -220,7 +188,8 @@ static void use_config(const char *m, int slen) return; define_config(m, slen, hash); - print_dep(m, slen, "include/config"); + /* Print out a dependency path from a symbol name. */ + xprintf(" $(wildcard include/config/%.*s) \\\n", slen, m); } /* test if s ends in sub */ diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 2568dbe16ed6..c7b7e1c62a9c 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -130,19 +130,14 @@ static size_t depfile_prefix_len; static int conf_touch_dep(const char *name) { int fd, ret; - const char *s; - char *d, c; + char *d; - /* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */ - if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path)) + /* check overflow: prefix + name + '\0' must fit in buffer. */ + if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path)) return -1; d = depfile_path + depfile_prefix_len; - s = name; - - while ((c = *s++)) - *d++ = (c == '_') ? '/' : tolower(c); - strcpy(d, ".h"); + strcpy(d, name); /* Assume directory path already exists. */ fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); @@ -465,7 +460,7 @@ load: * Reading from include/config/auto.conf * If CONFIG_FOO previously existed in * auto.conf but it is missing now, - * include/config/foo.h must be touched. + * include/config/FOO must be touched. */ conf_touch_dep(line + strlen(CONFIG_)); else -- cgit v1.2.3