LD_DEAD_CODE_DATA_ELIMINATION fixes and enabling for powerpc
Subsystems (3)
Nicholas Piggin
reviewerv2 cover LD_DEAD_CODE_DATA_ELIMINATION fixes and enabling for powerpc
v2 changes only patch 4, updates the changelog with ppc32 numbers and Tested-by tags, and also use TEXT_MAIN in the linker script as Christophe suggested.
Thanks,
Nick
Nicholas Piggin (4):
kbuild: Fix asm-generic/vmlinux.lds.h for
LD_DEAD_CODE_DATA_ELIMINATION
kbuild: LD_DEAD_CODE_DATA_ELIMINATION no
-ffunction-sections/-fdata-sections for module build
kbuild: Allow LD_DEAD_CODE_DATA_ELIMINATION to be selectable if
enabled
powerpc: Allow LD_DEAD_CODE_DATA_ELIMINATION to be selected
Makefile | 4 +-- arch/Kconfig | 15 ---------- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/vmlinux.lds.S | 22 +++++++------- include/asm-generic/vmlinux.lds.h | 49 ++++++++++++++++++------------- init/Kconfig | 27 +++++++++++++++++ 6 files changed, 70 insertions(+), 48 deletions(-)
Signature · 1 line
2.17.0
Nicholas Piggin
reviewerPATCH v2 1/4 kbuild: Fix asm-generic/vmlinux.lds.h for LD_DEAD_CODE_DATA_ELIMINATION
KEEP more tables, and add the function/data section wildcard to more section selections.
This is a little ad-hoc at the moment, but kernel code should be moved to consistently use .text..x (note: double dots) for explicit sections and all references to it in the linker script can be made with TEXT_MAIN, and similarly for other sections.
For now, let's see if major architectures move to enabling this option then we can do some refactoring passes. Otherwise if it remains unused or superseded by LTO, this may not be required.
--- include/asm-generic/vmlinux.lds.h | 49 ++++++++++++++++++------------- 1 file changed, 29 insertions(+), 20 deletions(-)
include/asm-generic/vmlinux.lds.h +29 -20
@@ -64,15 +64,24 @@* generates .data.identifier sections, which need to be pulled in with * .data. We don't want to pull in .data..other sections, which Linux * has defined. Same for text and bss. +* +* RODATA_MAIN is not used because existing code already defines .rodata.x +* sections to be brought in with rodata. */ #ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION #define TEXT_MAIN .text .text.[0-9a-zA-Z_]*#define DATA_MAIN .data .data.[0-9a-zA-Z_]* +#define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* +#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]*#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* +#define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]*#else #define TEXT_MAIN .text#define DATA_MAIN .data +#define SDATA_MAIN .sdata +#define RODATA_MAIN .rodata#define BSS_MAIN .bss +#define SBSS_MAIN .sbss#endif /*
@@ -105,7 +114,7 @@#ifdef CONFIG_FTRACE_MCOUNT_RECORD #define MCOUNT_REC () . = ALIGN(8); \ VMLINUX_SYMBOL(__start_mcount_loc) = .; \ - *(__mcount_loc) \ + KEEP(*(__mcount_loc)) \ VMLINUX_SYMBOL(__stop_mcount_loc) = .;#else #define MCOUNT_REC ()
@@ -113,7 +122,7 @@#ifdef CONFIG_TRACE_BRANCH_PROFILING #define LIKELY_PROFILE () VMLINUX_SYMBOL(__start_annotated_branch_profile) = .; \ - *(_ftrace_annotated_branch) \ + KEEP(*(_ftrace_annotated_branch)) \ VMLINUX_SYMBOL(__stop_annotated_branch_profile) = .;#else #define LIKELY_PROFILE ()
@@ -121,7 +130,7 @@#ifdef CONFIG_PROFILE_ALL_BRANCHES #define BRANCH_PROFILE () VMLINUX_SYMBOL(__start_branch_profile) = .; \ - *(_ftrace_branch) \ + KEEP(*(_ftrace_branch)) \ VMLINUX_SYMBOL(__stop_branch_profile) = .;#else #define BRANCH_PROFILE ()
@@ -238,8 +247,8 @@ *(DATA_MAIN) \ *(.ref.data) \ *(.data..shared_aligned) /* percpu related */ \ - MEM_KEEP(init.data) \ -MEM_KEEP (exit.data) \ + MEM_KEEP(init.data*) \ + MEM_KEEP(exit.data*) \ *(.data.unlikely) \ VMLINUX_SYMBOL(__start_once) = .; \ *(.data.once) \
@@ -289,8 +298,8 @@ VMLINUX_SYMBOL(__start_init_task) = .; \ VMLINUX_SYMBOL(init_thread_union) = .; \ VMLINUX_SYMBOL(init_stack) = .; \ - *(.data..init_task) \ - *(.data..init_thread_info) \ + KEEP(*(.data..init_task)) \ + KEEP(*(.data..init_thread_info)) \ . = VMLINUX_SYMBOL(__start_init_task) + THREAD_SIZE; \ VMLINUX_SYMBOL(__end_init_task) = .;
@@ -487,8 +496,8 @@ *(.text.hot TEXT_MAIN .text.fixup .text.unlikely) \ *(.text..refcount) \ *(.ref.text) \ - MEM_KEEP(init.text) \ -MEM_KEEP (exit.text) \ + MEM_KEEP(init.text*) \ + MEM_KEEP(exit.text*) \ /* sched.text is aling to function alignment to secure we have same
@@ -538,7 +547,7 @@ VMLINUX_SYMBOL(__softirqentry_text_end) = .;/* Section used for early init (in .S files) */ -#define HEAD_TEXT *(.head.text) +#define HEAD_TEXT KEEP(*(.head.text))#define HEAD_TEXT_SECTION \ .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) { \
@@ -579,11 +588,11 @@/* init and exit section handling */ #define INIT_DATA \ KEEP(*(SORT(___kentry+*))) \ - *(.init.data) \ - MEM_DISCARD(init.data) \ + *(.init.data init.data.*) \ + MEM_DISCARD(init.data*) \ KERNEL_CTORS() \ MCOUNT_REC() \ - *(.init.rodata) \ + *(.init.rodata .init.rodata.*) \ FTRACE_EVENTS() \ TRACE_SYSCALLS() \ KPROBE_BLACKLIST() \
@@ -602,16 +611,16 @@ EARLYCON_TABLE()#define INIT_TEXT \ - *(.init.text) \ + *(.init.text .init.text.*) \ *(.text.startup) \ - MEM_DISCARD(init.text) + MEM_DISCARD(init.text*)#define EXIT_DATA \ - *(.exit.data) \ + *(.exit.data .exit.data.*) \ *(.fini_array) \ *(.dtors) \ - MEM_DISCARD(exit.data) \ - MEM_DISCARD(exit.rodata) + MEM_DISCARD(exit.data*) \ + MEM_DISCARD(exit.rodata*)#define EXIT_TEXT \ *(.exit.text) \
@@ -629,7 +638,7 @@ . = ALIGN(sbss_align); \ .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) { \ *(.dynsbss) \ - *(.sbss) \ + *(SBSS_MAIN ) \ *(.scommon) \ }
@@ -754,7 +763,7 @@#define NOTES \ .notes : AT(ADDR(.notes) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_notes) = .; \ - *(.note.*) \ + KEEP(*(.note.*)) \ VMLINUX_SYMBOL(__stop_notes) = .; \ }
Signature · 1 line
2.17.0
Nicholas Piggin
reviewerPATCH v2 2/4 kbuild: LD_DEAD_CODE_DATA_ELIMINATION no -ffunction-sections/-fdata-sections for module build
In reply to Nicholas PigginModules do not tend to cope with -ffunction-sections, even though they do not link with -gc-sections. It may be possible for unused symbols to be trimmed from modules, but in general that would take much more work in architecture module linker scripts.
For now, enable these only for kernel build.
--- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Makefile +2 -2
@@ -799,8 +799,8 @@ KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once) endif ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION -KBUILD_CFLAGS += $(call cc-option,-ffunction-sections,) -KBUILD_CFLAGS += $(call cc-option,-fdata-sections,) +KBUILD_CFLAGS_KERNEL += $(call cc-option,-ffunction-sections,) +KBUILD_CFLAGS_KERNEL += $(call cc-option,-fdata-sections,) endif # arch Makefile may override CC so keep this after arch Makefile is included
Signature · 1 line
2.17.0
Nicholas Piggin
reviewerPATCH v2 3/4 kbuild: Allow LD_DEAD_CODE_DATA_ELIMINATION to be selectable if enabled
In reply to Nicholas PigginArchitectures that are capable can select HAVE_LD_DEAD_CODE_DATA_ELIMINATION to enable selection of that option (as an EXPERT kernel option).
--- arch/Kconfig | 15 --------------- init/Kconfig | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 15 deletions(-)
arch/Kconfig +0 -15
@@ -596,21 +596,6 @@ config CC_STACKPROTECTOR_AUTO endchoice -config LD_DEAD_CODE_DATA_ELIMINATION - bool - help - Select this if the architecture wants to do dead code and - data elimination with the linker by compiling with - -ffunction-sections -fdata-sections and linking with - --gc-sections. - - This requires that the arch annotates or otherwise protects - its external entry points from being discarded. Linker scripts - must also merge .text.*, .data.*, and .bss.* correctly into - output sections. Care must be taken not to pull in unrelated - sections (e.g., '.text.init'). Typically '.' in section names - is used to distinguish them from label names / C identifiers. - config HAVE_ARCH_WITHIN_STACK_FRAMES bool help
init/Kconfig +27 -0
@@ -1038,6 +1038,33 @@ config CC_OPTIMIZE_FOR_SIZE endchoice +config HAVE_LD_DEAD_CODE_DATA_ELIMINATION + bool + help + This requires that the arch annotates or otherwise protects + its external entry points from being discarded. Linker scripts + must also merge .text.*, .data.*, and .bss.* correctly into + output sections. Care must be taken not to pull in unrelated + sections (e.g., '.text.init'). Typically '.' in section names + is used to distinguish them from label names / C identifiers. + +config LD_DEAD_CODE_DATA_ELIMINATION + bool "Dead code and data elimination (EXPERIMENTAL)" + depends on HAVE_LD_DEAD_CODE_DATA_ELIMINATION + depends on EXPERT + help + Select this if the architecture wants to do dead code and + data elimination with the linker by compiling with + -ffunction-sections -fdata-sections, and linking with + --gc-sections. + + This can reduce on disk and in-memory size of the kernel + code and static data, particularly for small configs and + on small systems. This has the possibility of introducing + silently broken kernel if the required annotations are not + present. This option is not well tested yet, so use at your + own risk. + config SYSCTL bool
Signature · 1 line
2.17.0
Nicholas Piggin
reviewerPATCH v2 4/4 powerpc: Allow LD_DEAD_CODE_DATA_ELIMINATION to be selected
In reply to Nicholas PigginThis requires further changes to linker script to KEEP some tables and wildcard compiler generated sections into the right place. This includes pp32 modifications from Christophe Leroy.
When compiling powernv_defconfig with this option, the resulting kernel is almost 400kB smaller (and still boots):
text data bss dec filename 11827621 4810490 1341080 17979191 vmlinux 11752437 4598858 1338776 17690071 vmlinux.dcde
Mathieu's numbers for custom Mac Mini G4 config has almost 200kB saving. It also had some increase in vmlinux size for as-yet unknown reasons.
text data bss dec filename 7461457 2475122 1428064 11364643 vmlinux 7386425 2364370 1425432 11176227 vmlinux.dcde
--- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/vmlinux.lds.S | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-)
arch/powerpc/Kconfig +1 -0
@@ -205,6 +205,7 @@ config PPC select HAVE_KPROBES select HAVE_KPROBES_ON_FTRACE select HAVE_KRETPROBES + select HAVE_LD_DEAD_CODE_DATA_ELIMINATION select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP
arch/powerpc/kernel/vmlinux.lds.S +11 -11
@@ -89,7 +89,7 @@ SECTIONS */ .text BLOCK(0) : AT(ADDR(.text) - LOAD_OFFSET) { #ifdef CONFIG_LD_HEAD_STUB_CATCH - *(.linker_stub_catch); + KEEP(*(.linker_stub_catch)); . = . ; #endif
@@ -98,7 +98,7 @@ SECTIONS ALIGN_FUNCTION(); #endif /* careful! __ftr_alt_* sections need to be close to .text */ - *(.text.hot .text .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); + *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); SCHED_TEXT CPUIDLE_TEXT LOCK_TEXT
@@ -170,10 +170,10 @@ SECTIONS .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { INIT_DATA __vtop_table_begin = .; - *(.vtop_fixup); + KEEP(*(.vtop_fixup)); __vtop_table_end = .; __ptov_table_begin = .; - *(.ptov_fixup); + KEEP(*(.ptov_fixup)); __ptov_table_end = .; }
@@ -194,26 +194,26 @@ SECTIONS . = ALIGN(8); __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) { __start___ftr_fixup = .; - *(__ftr_fixup) + KEEP(*(__ftr_fixup)) __stop___ftr_fixup = .; } . = ALIGN(8); __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) { __start___mmu_ftr_fixup = .; - *(__mmu_ftr_fixup) + KEEP(*(__mmu_ftr_fixup)) __stop___mmu_ftr_fixup = .; } . = ALIGN(8); __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) { __start___lwsync_fixup = .; - *(__lwsync_fixup) + KEEP(*(__lwsync_fixup)) __stop___lwsync_fixup = .; } #ifdef CONFIG_PPC64 . = ALIGN(8); __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) { __start___fw_ftr_fixup = .; - *(__fw_ftr_fixup) + KEEP(*(__fw_ftr_fixup)) __stop___fw_ftr_fixup = .; } #endif
@@ -226,7 +226,7 @@ SECTIONS . = ALIGN(8); .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) { __machine_desc_start = . ; - *(.machine.desc) + KEEP(*(.machine.desc)) __machine_desc_end = . ; } #ifdef CONFIG_RELOCATABLE
@@ -274,7 +274,7 @@ SECTIONS .data : AT(ADDR(.data) - LOAD_OFFSET) { DATA_DATA *(.data.rel*) - *(.sdata) + *(SDATA_MAIN) *(.sdata2) *(.got.plt) *(.got) *(.plt)
@@ -289,7 +289,7 @@ SECTIONS .opd : AT(ADDR(.opd) - LOAD_OFFSET) { __start_opd = .; - *(.opd) + KEEP(*(.opd)) __end_opd = .; }
Signature · 1 line
2.17.0
Re: [PATCH v2 4/4] powerpc: Allow LD_DEAD_CODE_DATA_ELIMINATION to be selected
Quoted 19 lines · Nicholas Piggin
This requires further changes to linker script to KEEP some tables and wildcard compiler generated sections into the right place. This includes pp32 modifications from Christophe Leroy.
When compiling
powernv_defconfigwith this option, the resulting kernel is almost 400kB smaller (and still boots):text data bss dec filename 11827621 4810490 1341080 17979191 vmlinux 11752437 4598858 1338776 17690071 vmlinux.dcdeMathieu's numbers for custom Mac Mini G4 config has almost 200kB saving. It also had some increase in vmlinux size for as-yet unknown reasons.
text data bss dec filename 7461457 2475122 1428064 11364643 vmlinux 7386425 2364370 1425432 11176227 vmlinux.dcde
Quoted 7 lines
Signed-off-by Nicholas Piggin <[email protected]>--- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/vmlinux.lds.S | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-)
I'm happy for this to go in via the kbuild tree.
As long as it's in linux-next it will get tested by my CI which should hopefully shake out any bugs.
cheers
Re: [PATCH v2 4/4] powerpc: Allow LD_DEAD_CODE_DATA_ELIMINATION to be selected
In reply to Nicholas PigginQuoted 4 lines · Nicholas Piggin
This requires further changes to linker script to KEEP some tables and wildcard compiler generated sections into the right place. This includes pp32 modifications from Christophe Leroy.
Quoted 8 lines
When compiling
powernv_defconfigwith this option, the resulting kernel is almost 400kB smaller (and still boots):text data bss dec filename 11827621 4810490 1341080 17979191 vmlinux 11752437 4598858 1338776 17690071 vmlinux.dcdeMathieu's numbers for custom Mac Mini G4 config has almost 200kB
Technically this is an oldconfig from debian original config file (debian official powerpc kernel package)... tested on a mac mini g4.
Quoted 123 lines
saving. It also had some increase in vmlinux size for as-yet unknown reasons.
text data bss dec filename 7461457 2475122 1428064 11364643 vmlinux 7386425 2364370 1425432 11176227 vmlinux.dcdeSigned-off-by Nicholas Piggin <[email protected]>--- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/vmlinux.lds.S | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-)arch/powerpc/Kconfig +1
-0@@ -205,6 +205,7 @@ config PPC select HAVE_KPROBES select HAVE_KPROBES_ON_FTRACE select HAVE_KRETPROBES + select HAVE_LD_DEAD_CODE_DATA_ELIMINATION select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAParch/powerpc/kernel/vmlinux.lds.S +11
-12@@ -89,7 +89,7 @@ SECTIONS */ .text BLOCK(0) : AT(ADDR(.text) - LOAD_OFFSET) { #ifdef CONFIG_LD_HEAD_STUB_CATCH - *(.linker_stub_catch); + KEEP(*(.linker_stub_catch)); . = . ; #endif@@ -98,7 +98,7 @@ SECTIONS ALIGN_FUNCTION(); #endif /* careful! __ftr_alt_* sections need to be close to .text */ - *(.text.hot .text .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); + *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); SCHED_TEXT CPUIDLE_TEXT LOCK_TEXT@@ -170,10 +170,10 @@ SECTIONS .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { INIT_DATA __vtop_table_begin = .; - *(.vtop_fixup); + KEEP(*(.vtop_fixup)); __vtop_table_end = .; __ptov_table_begin = .; - *(.ptov_fixup); + KEEP(*(.ptov_fixup)); __ptov_table_end = .; }@@ -194,26 +194,26 @@ SECTIONS . = ALIGN(8); __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) { __start___ftr_fixup = .; - *(__ftr_fixup) + KEEP(*(__ftr_fixup)) __stop___ftr_fixup = .; } . = ALIGN(8); __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) { __start___mmu_ftr_fixup = .; - *(__mmu_ftr_fixup) + KEEP(*(__mmu_ftr_fixup)) __stop___mmu_ftr_fixup = .; } . = ALIGN(8); __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) { __start___lwsync_fixup = .; - *(__lwsync_fixup) + KEEP(*(__lwsync_fixup)) __stop___lwsync_fixup = .; } #ifdef CONFIG_PPC64 . = ALIGN(8); __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) { __start___fw_ftr_fixup = .; - *(__fw_ftr_fixup) + KEEP(*(__fw_ftr_fixup)) __stop___fw_ftr_fixup = .; } #endif@@ -226,7 +226,7 @@ SECTIONS . = ALIGN(8); .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) { __machine_desc_start = . ; - *(.machine.desc) + KEEP(*(.machine.desc)) __machine_desc_end = . ; } #ifdef CONFIG_RELOCATABLE@@ -274,7 +274,7 @@ SECTIONS .data : AT(ADDR(.data) - LOAD_OFFSET) { DATA_DATA *(.data.rel*) - *(.sdata) + *(SDATA_MAIN) *(.sdata2) *(.got.plt) *(.got) *(.plt)@@ -289,7 +289,7 @@ SECTIONS .opd : AT(ADDR(.opd) - LOAD_OFFSET) { __start_opd = .; - *(.opd) + KEEP(*(.opd)) __end_opd = .; } --2.17.0
2018-05-09 21:59 GMT+09:00 Nicholas Piggin <[email protected]>:
Quoted 3 lines
v2 changes only patch 4, updates the changelog with ppc32 numbers and Tested-by tags, and also use
TEXT_MAINin the linker script as Christophe suggested.
Replaced with v2.
Thanks!
Quoted 27 lines
Thanks,
NickNicholas Piggin (4):
kbuild: Fixasm-generic/vmlinux.lds.hfor
LD_DEAD_CODE_DATA_ELIMINATION
kbuild:LD_DEAD_CODE_DATA_ELIMINATIONno
-ffunction-sections/-fdata-sections for module build
kbuild: AllowLD_DEAD_CODE_DATA_ELIMINATIONto be selectable if
enabled
powerpc: AllowLD_DEAD_CODE_DATA_ELIMINATIONto be selectedMakefile | 4 +-- arch/Kconfig | 15 ---------- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/vmlinux.lds.S | 22 +++++++------- include/asm-generic/vmlinux.lds.h | 49 ++++++++++++++++++------------- init/Kconfig | 27 +++++++++++++++++ 6 files changed, 70 insertions(+), 48 deletions(-)--
2.17.0--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
Best Regards Masahiro Yamada