Skip to content

Commit

Permalink
kbuild: re-implement CONFIG_TRIM_UNUSED_KSYMS to make it work in one-…
Browse files Browse the repository at this point in the history
…pass

Commit a555bdd ("Kbuild: enable TRIM_UNUSED_KSYMS again, with some
guarding") re-enabled this feature, but Linus is still unhappy about
the build time.

The reason of the slowness is the recursion - after updating
<generated/autoksyms.h> (, which contains all symbols needed by modules),
Kbuild begins the second traverse, rebuilding objects whose EXPORT_SYMBOL
needs flipping.

This commit re-implements CONFIG_TRIM_UNUSED_KSYMS to make it work
in one pass. After the tree traverse, a linker script snippet
<generated/keep-ksyms.h> is generated. It feeds the list of necessary
sections to vmlinus.lds.S and modules.lds.S. The other sections fall
into DISCARDS.

There is no more build issue, I believe. I dropped the 'if EXPORT' and
'depends on !COMPILE_TEST' guarding.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
  • Loading branch information
masahir0y authored and intel-lab-lkp committed Feb 25, 2021
1 parent 839699e commit 0149403
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 214 deletions.
30 changes: 12 additions & 18 deletions Makefile
Expand Up @@ -1160,29 +1160,23 @@ export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds
# used by scripts/Makefile.package
export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) LICENSES arch include scripts tools)

vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS)
targets :=

# Recurse until adjust_autoksyms.sh is satisfied
PHONY += autoksyms_recursive
ifdef CONFIG_TRIM_UNUSED_KSYMS
# For the kernel to actually contain only the needed exported symbols,
# we have to build modules as well to determine what those symbols are.
# (this can be evaluated only once include/config/auto.conf has been included)
KBUILD_MODULES := 1

autoksyms_recursive: descend modules.order
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \
"$(MAKE) -f $(srctree)/Makefile vmlinux"
endif

autoksyms_h := $(if $(CONFIG_TRIM_UNUSED_KSYMS), include/generated/autoksyms.h)
quiet_cmd_gen_used_ksyms = GEN $@
cmd_gen_used_ksyms = $(CONFIG_SHELL) $(srctree)/scripts/gen-keep-ksyms.sh $< > $@

quiet_cmd_autoksyms_h = GEN $@
cmd_autoksyms_h = mkdir -p $(dir $@); \
$(CONFIG_SHELL) $(srctree)/scripts/gen_autoksyms.sh $@
include/generated/keep-ksyms.h: modules.order FORCE
$(call if_changed,gen_used_ksyms)
targets += include/generated/keep-ksyms.h

$(autoksyms_h):
$(call cmd,autoksyms_h)
$(KBUILD_LDS) modules_prepare: include/generated/keep-ksyms.h
endif

$(KBUILD_LDS): prepare FORCE
$(Q)$(MAKE) $(build)=$(patsubst %/,%,$(dir $@)) $@
Expand All @@ -1194,11 +1188,11 @@ cmd_link-vmlinux = \
$(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)

vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(KBUILD_LDS) \
vmlinux: scripts/link-vmlinux.sh $(KBUILD_LDS) \
$(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE
+$(call if_changed,link-vmlinux)

targets := vmlinux
targets += vmlinux

# The actual objects are generated when descending,
# make sure no implicit rule kicks in
Expand Down Expand Up @@ -1227,7 +1221,7 @@ scripts: scripts_basic scripts_dtc
PHONY += prepare archprepare

archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \
asm-generic $(version_h) $(autoksyms_h) include/generated/utsrelease.h \
asm-generic $(version_h) include/generated/utsrelease.h \
include/generated/autoconf.h

prepare0: archprepare
Expand Down Expand Up @@ -1503,7 +1497,7 @@ endif # CONFIG_MODULES
# make distclean Remove editor backup files, patch leftover files and the like

# Directories & files removed with 'make clean'
CLEAN_FILES += include/ksym vmlinux.symvers \
CLEAN_FILES += vmlinux.symvers \
modules.builtin modules.builtin.modinfo modules.nsdeps \
compile_commands.json

Expand Down
23 changes: 0 additions & 23 deletions include/asm-generic/export.h
Expand Up @@ -57,30 +57,7 @@ __kstrtab_\name:
#endif
.endm

#if defined(CONFIG_TRIM_UNUSED_KSYMS)

#include <linux/kconfig.h>
#include <generated/autoksyms.h>

.macro __ksym_marker sym
.section ".discard.ksym","a"
__ksym_marker_\sym:
.previous
.endm

#define __EXPORT_SYMBOL(sym, val, sec) \
__ksym_marker sym; \
__cond_export_sym(sym, val, sec, __is_defined(__KSYM_##sym))
#define __cond_export_sym(sym, val, sec, conf) \
___cond_export_sym(sym, val, sec, conf)
#define ___cond_export_sym(sym, val, sec, enabled) \
__cond_export_sym_##enabled(sym, val, sec)
#define __cond_export_sym_1(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec
#define __cond_export_sym_0(sym, val, sec) /* nothing */

#else
#define __EXPORT_SYMBOL(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec
#endif

#define EXPORT_SYMBOL(name) \
__EXPORT_SYMBOL(name, KSYM_FUNC(name),)
Expand Down
29 changes: 24 additions & 5 deletions include/asm-generic/vmlinux.lds.h
Expand Up @@ -50,6 +50,24 @@
* [__nosave_begin, __nosave_end] for the nosave data
*/

#if CONFIG_TRIM_UNUSED_KSYMS
#include <generated/keep-ksyms.h>

#define KSYM_DISCARDS *(___ksymtab+*) \
*(___ksymtab_gpl+*) \
*(___kcrctab+*) \
*(___kcrctab_gpl+*) \
*(__ksymtab_strings+*)

#else
#define KSYMTAB KEEP(*(SORT(___ksymtab+*)))
#define KSYMTAB_GPL KEEP(*(SORT(___ksymtab_gpl+*)))
#define KCRCTAB KEEP(*(SORT(___kcrctab+*)))
#define KCRCTAB_GPL KEEP(*(SORT(___kcrctab_gpl+*)))
#define KSYMTAB_STRINGS *(__ksymtab_strings+*)
#define KSYM_DISCARDS
#endif

#ifndef LOAD_OFFSET
#define LOAD_OFFSET 0
#endif
Expand Down Expand Up @@ -486,34 +504,34 @@
/* Kernel symbol table: Normal symbols */ \
__ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
__start___ksymtab = .; \
KEEP(*(SORT(___ksymtab+*))) \
KSYMTAB \
__stop___ksymtab = .; \
} \
\
/* Kernel symbol table: GPL-only symbols */ \
__ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
__start___ksymtab_gpl = .; \
KEEP(*(SORT(___ksymtab_gpl+*))) \
KSYMTAB_GPL \
__stop___ksymtab_gpl = .; \
} \
\
/* Kernel symbol table: Normal symbols */ \
__kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \
__start___kcrctab = .; \
KEEP(*(SORT(___kcrctab+*))) \
KCRCTAB \
__stop___kcrctab = .; \
} \
\
/* Kernel symbol table: GPL-only symbols */ \
__kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \
__start___kcrctab_gpl = .; \
KEEP(*(SORT(___kcrctab_gpl+*))) \
KCRCTAB_GPL \
__stop___kcrctab_gpl = .; \
} \
\
/* Kernel symbol table: strings */ \
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
*(__ksymtab_strings+*) \
KSYMTAB_STRINGS \
} \
\
/* __*init sections */ \
Expand Down Expand Up @@ -993,6 +1011,7 @@
/DISCARD/ : { \
EXIT_DISCARDS \
EXIT_CALL \
KSYM_DISCARDS \
COMMON_DISCARDS \
}

Expand Down
54 changes: 12 additions & 42 deletions include/linux/export.h
Expand Up @@ -76,9 +76,18 @@ struct kernel_symbol {
};
#endif

#ifdef __GENKSYMS__
#if !defined(CONFIG_MODULES) || defined(__DISABLE_EXPORTS)

/*
* Allow symbol exports to be disabled completely so that C code may
* be reused in other execution contexts such as the UEFI stub or the
* decompressor.
*/
#define __EXPORT_SYMBOL(sym, sec, ns)

#elif defined(__GENKSYMS__)

#define ___EXPORT_SYMBOL(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)
#define __EXPORT_SYMBOL(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym)

#else

Expand All @@ -94,7 +103,7 @@ struct kernel_symbol {
* section flag requires it. Use '%progbits' instead of '@progbits' since the
* former apparently works on all arches according to the binutils source.
*/
#define ___EXPORT_SYMBOL(sym, sec, ns) \
#define __EXPORT_SYMBOL(sym, sec, ns) \
extern typeof(sym) sym; \
extern const char __kstrtab_##sym[]; \
extern const char __kstrtabns_##sym[]; \
Expand All @@ -107,45 +116,6 @@ struct kernel_symbol {
" .previous \n"); \
__KSYMTAB_ENTRY(sym, sec)

#endif

#if !defined(CONFIG_MODULES) || defined(__DISABLE_EXPORTS)

/*
* Allow symbol exports to be disabled completely so that C code may
* be reused in other execution contexts such as the UEFI stub or the
* decompressor.
*/
#define __EXPORT_SYMBOL(sym, sec, ns)

#elif defined(CONFIG_TRIM_UNUSED_KSYMS)

#include <generated/autoksyms.h>

/*
* For fine grained build dependencies, we want to tell the build system
* about each possible exported symbol even if they're not actually exported.
* We use a symbol pattern __ksym_marker_<symbol> that the build system filters
* from the $(NM) output (see scripts/gen_ksymdeps.sh). These symbols are
* discarded in the final link stage.
*/
#define __ksym_marker(sym) \
static int __ksym_marker_##sym[0] __section(".discard.ksym") __used

#define __EXPORT_SYMBOL(sym, sec, ns) \
__ksym_marker(sym); \
__cond_export_sym(sym, sec, ns, __is_defined(__KSYM_##sym))
#define __cond_export_sym(sym, sec, ns, conf) \
___cond_export_sym(sym, sec, ns, conf)
#define ___cond_export_sym(sym, sec, ns, enabled) \
__cond_export_sym_##enabled(sym, sec, ns)
#define __cond_export_sym_1(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)
#define __cond_export_sym_0(sym, sec, ns) /* nothing */

#else

#define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns)

#endif /* CONFIG_MODULES */

#ifdef DEFAULT_SYMBOL_NAMESPACE
Expand Down
3 changes: 1 addition & 2 deletions init/Kconfig
Expand Up @@ -2259,8 +2259,7 @@ config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS
If unsure, say N.

config TRIM_UNUSED_KSYMS
bool "Trim unused exported kernel symbols" if EXPERT
depends on !COMPILE_TEST
bool "Trim unused exported kernel symbols"
help
The kernel and some modules make many symbols available for
other modules to use via EXPORT_SYMBOL() and variants. Depending
Expand Down
5 changes: 0 additions & 5 deletions scripts/Makefile.build
Expand Up @@ -245,16 +245,12 @@ objtool_dep = $(objtool_obj) \
include/config/stack/validation.h)

ifdef CONFIG_TRIM_UNUSED_KSYMS
cmd_gen_ksymdeps = \
$(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd

# List module undefined symbols
undefined_syms = $(NM) $< | $(AWK) '$$1 == "U" { printf("%s%s", x++ ? " " : "", $$2) }';
endif

define rule_cc_o_c
$(call cmd_and_fixdep,cc_o_c)
$(call cmd,gen_ksymdeps)
$(call cmd,checksrc)
$(call cmd,checkdoc)
$(call cmd,objtool)
Expand All @@ -264,7 +260,6 @@ endef

define rule_as_o_S
$(call cmd_and_fixdep,as_o_S)
$(call cmd,gen_ksymdeps)
$(call cmd,objtool)
$(call cmd,modversions_S)
endef
Expand Down
76 changes: 0 additions & 76 deletions scripts/adjust_autoksyms.sh

This file was deleted.

0 comments on commit 0149403

Please sign in to comment.