[PATCH 0/4] build system: section garbage collection for vmlinux

Previous thread: [announce] CFS-devel, performance improvements by Ingo Molnar on Tuesday, September 11, 2007 - 4:04 pm. (44 messages)

Next thread: [PATCH 23/23] debug: sysfs files for the current ratio/size/total by Peter Zijlstra on Tuesday, September 11, 2007 - 3:54 pm. (1 message)
To: Sam Ravnborg <sam@...>
Cc: <linux-kernel@...>
Date: Tuesday, September 11, 2007 - 4:05 pm

Build system: section garbage collection for vmlinux

Newer gcc and binutils can do dead code and data removal
at link time. It is achieved using combination of
-ffunction-sections -fdata-sections options for gcc and
--gc-sections for ld.

Theory of operation:

Option -ffunction-sections instructs gcc to place each function
(including static ones) in it's own section named .text.function_name
instead of placing all functions in one big .text section.

At link time, ld normally coalesce all such sections into one
output section .text again. It is achieved by having *(.text.*) spec
along with *(.text) spec in built-in linker scripts.

If ld is invoked with --gc-sections, it tracks references, starting
from entry point and marks all input sections which are reachable
from there. Then it discards all input sections which are not marked.

This isn't buying much if you have one big .text section per .o module,
because even one referenced function will pull in entire section.
You need -ffunction-sections in order to split .text into per-function
sections and make --gc-sections much more useful.

-fdata-sections is analogous: it places each global or static variable
into .data.variable_name, .rodata.variable_name or .bss.variable_name.

How to use it in kernel:

First, we need to adapt existing code for new section names.
Basically, we need to stop using section names of the form
.text.xxxx
.data.xxxx
.rodata.xxxx
.bss.xxxx
in the kernel for - otherwise section placement done by kernel's
custom linker scripts produces broken vmlinux and vdso images.

Second, kernel linker scripts need to be adapted by adding KEEP(xxx)
directives around sections which are not directly referenced, but are
nevertheless used (initcalls, altinstructions, etc).

These patches fix section names and add
CONFIG_DISCARD_UNUSED_SECTIONS. It is not enabled
unconditionally because only newest binutils have
ld --gc-sections which is stable enough for kernel use.
IOW: this is an experimental feature for n...

To: Denys Vlasenko <vda.linux@...>
Cc: Sam Ravnborg <sam@...>, <linux-kernel@...>
Date: Thursday, September 13, 2007 - 2:26 pm

This is good stuff. I had been using a ported variant of this
optimization for ARM on quite an older 2.6 kernel for a while now. I
derived that port from:
http://lkml.org/lkml/2006/6/4/169

With some tweaks it worked for me. Could you also have a look at the
mentioned link and see if that's a superset of what you're trying to
achieve?

--
Abhishek Sagar
-

To: Abhishek Sagar <sagar.abhishek@...>
Cc: Denys Vlasenko <vda.linux@...>, <linux-kernel@...>
Date: Thursday, September 13, 2007 - 2:35 pm

Hi Abhisshek.

Could you post your tweaked version - against an older kernel is OK.

Sam
-

To: Sam Ravnborg <sam@...>
Cc: Denys Vlasenko <vda.linux@...>, <linux-kernel@...>
Date: Friday, September 14, 2007 - 2:06 pm

The inlined patch should apply cleanly on top of the patch posted on
the link I mentioned before. The *.S files are the ones I chose to
bring them under the purview of --ffunction-sections. My observation
remains that if a fine-grained function/data/exported-symbol level
garbage collection can be incorporated into the build environment,
then it'll be something really useful.

--
Abhishek Sagar

---
diff -upNr linux_orig-2.6.12/arch/arm/kernel/armksyms.c
linux-2.6.12/arch/arm/kernel/armksyms.c
--- linux_orig-2.6.12/arch/arm/kernel/armksyms.c 2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/kernel/armksyms.c 2007-09-14 09:00:03.000000000 +0530
@@ -44,10 +44,17 @@ extern void fp_enter(void);
* This has a special calling convention; it doesn't
* modify any of the usual registers, except for LR.
*/
+#ifndef CONFIG_GCSECTIONS
#define EXPORT_SYMBOL_ALIAS(sym,orig) \
const struct kernel_symbol __ksymtab_##sym \
__attribute__((section("__ksymtab"))) = \
{ (unsigned long)&orig, #sym };
+#else
+#define EXPORT_SYMBOL_ALIAS(sym,orig) \
+ const struct kernel_symbol __ksymtab_##sym \
+ __attribute__((section("___ksymtab_" #sym))) = \
+ { (unsigned long)&orig, #sym };
+#endif /* CONFIG_GCSECTIONS */

/*
* floating point math emulator support.
diff -upNr linux_orig-2.6.12/arch/arm/kernel/iwmmxt.S
linux-2.6.12/arch/arm/kernel/iwmmxt.S
--- linux_orig-2.6.12/arch/arm/kernel/iwmmxt.S 2005-06-18
01:18:29.000000000 +0530
+++ linux-2.6.12/arch/arm/kernel/iwmmxt.S 2007-09-14 09:21:01.000000000 +0530
@@ -55,7 +55,11 @@
*
* called from prefetch exception handler with interrupts disabled
*/
-
+#ifdef CONFIG_GCSECTIONS
+ .section ".text.iwmmxt_task_enable"
+#else
+ .text
+#endif
ENTRY(iwmmxt_task_enable)

mrc p15, 0, r2, c15, c1, 0
diff -upNr linux_orig-2.6.12/arch/arm/kernel/vmlinux.lds.S
linux-2.6.12/arch/arm/kernel/vmlinux.lds.S
--- linux_orig-2.6.12/arch/arm/kernel/vmlinux.lds.S 2005-06-18
01:18:29...

To: Denys Vlasenko <vda.linux@...>
Cc: Sam Ravnborg <sam@...>, <linux-kernel@...>
Date: Tuesday, September 11, 2007 - 5:03 pm

>

To: Andi Kleen <andi@...>
Cc: Sam Ravnborg <sam@...>, <linux-kernel@...>
Date: Wednesday, September 12, 2007 - 4:19 pm

With CONFIG_DISCARD_UNUSED_SECTIONS=y ld will helpfully flood you
with the list of discarded stuff. I pass --print-gc-sections to it.
--
vda
-

To: Sam Ravnborg <sam@...>
Cc: <linux-kernel@...>
Date: Tuesday, September 11, 2007 - 4:07 pm

This patch is needed for --gc-sections to work, regardless
of which final form that support will have.

This patch renames .text.xxx and .data.xxx sections
into .xxx.text and .xxx.data, respectively.

.bss.page_aligned (the only .bss.xxx -like section we have)
is renamed .bss.k.page_aligned. ".page_aligned.bss"
wouldn't work - gcc will assign such section attributes
which make it unmergeable with .bss. In fact, binutils ld
had a bug and instead of complaining was producing
broken vmlinux. The bug is fixed in binutils. Amazingly
fast reaction from binutils folks to bug reports! Thanks!

.bss.k.page_aligned is more-or-less ok, since it cannot collide
with gcc-produced sections due to second dot in the name. However,
should we want to do this in linker script:

.bss : { *(.bss) *(.bss.*) *(.bss.k.page_aligned))

it wouldn't work. But currently we don't need that.

If patch doesn't apply to a newer kernel,
you can regenerate it by running linux-2.6.23-rc4.0.fixname.sh
in a kernel free and rediffing it against unmodified one.

Please apply.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

To: Denys Vlasenko <vda.linux@...>
Cc: Sam Ravnborg <sam@...>, <linux-kernel@...>
Date: Tuesday, September 11, 2007 - 5:47 pm

I think you'll have better luck with this if you focus on a single
architecture (i386 would be best) ..

Daniel

-

To: Daniel Walker <dwalker@...>
Cc: Sam Ravnborg <sam@...>, <linux-kernel@...>
Date: Wednesday, September 12, 2007 - 4:18 pm

I did exactly that. I focused on x86_64.

Of course, section name fixes cannot be done per-arch, as they
are scattered across entire tree.

Apart from that, it was x86_64 only.

By now, I also have patches for i386 in hand too.
--
vda
-

To: Denys Vlasenko <vda.linux@...>
Cc: Sam Ravnborg <sam@...>, <linux-kernel@...>
Date: Wednesday, September 12, 2007 - 4:52 pm

This is want I'm talking about .. Why can't you do this per
architecture?

Daniel

-

To: Sam Ravnborg <sam@...>
Cc: <linux-kernel@...>
Date: Tuesday, September 11, 2007 - 4:10 pm

This patch fixes x86_64 vdso image so that it builds with --gc-sections.

Then it fixes comment in arch/i386/kernel/vmlinux.lds.S
and adds comments to other linker scripts about .bss.

Please apply.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

To: Sam Ravnborg <sam@...>
Cc: <linux-kernel@...>
Date: Tuesday, September 11, 2007 - 4:11 pm

This patch makes modpost able to process object files with more than
64k sections. Needed for huge kernel builds (allyesconfig, for example)
with --gc-sections.

This patch basically fixes modpost, it isn't specific
for section garbage collection.

Please apply.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

To: Sam Ravnborg <sam@...>
Cc: <linux-kernel@...>
Date: Tuesday, September 11, 2007 - 4:22 pm

This is the core patch of the series.

It adds CONFIG_DISCARD_UNUSED_SECTIONS,
adds KEEP() directives to linker scripts,
adds custom module linker script which is needed
to avoid having modules with many small sections.
Modules got a bit smaller too, as a result.

This patch is slighty more risky than first three,
probably need to go into -mm first.
It should be safe with CONFIG_DISCARD_UNUSED_SECTIONS off, though.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
--
vda

Previous thread: [announce] CFS-devel, performance improvements by Ingo Molnar on Tuesday, September 11, 2007 - 4:04 pm. (44 messages)

Next thread: [PATCH 23/23] debug: sysfs files for the current ratio/size/total by Peter Zijlstra on Tuesday, September 11, 2007 - 3:54 pm. (1 message)