Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1455443 > unrolled thread
| Started by | "Luis R. Rodriguez" <mcgrof@kernel.org> |
|---|---|
| First post | 2016-08-02 22:10 +0200 |
| Last post | 2016-08-03 05:30 +0200 |
| Articles | 20 on this page of 31 — 7 participants |
Back to article view | Back to linux.kernel
powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures "Luis R. Rodriguez" <mcgrof@kernel.org> - 2016-08-02 22:10 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Guenter Roeck <linux@roeck-us.net> - 2016-08-03 00:00 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures "Luis R. Rodriguez" <mcgrof@kernel.org> - 2016-08-03 00:30 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-03 00:50 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Stephen Rothwell <sfr@canb.auug.org.au> - 2016-08-03 02:30 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-03 10:00 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Stephen Rothwell <sfr@canb.auug.org.au> - 2016-08-03 14:30 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-03 14:40 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Nicholas Piggin <npiggin@gmail.com> - 2016-08-03 18:00 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-03 21:10 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-03 22:20 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Segher Boessenkool <segher@kernel.crashing.org> - 2016-08-03 22:50 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Stephen Rothwell <sfr@canb.auug.org.au> - 2016-08-04 02:20 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-04 11:10 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-04 12:50 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Nicholas Piggin <npiggin@gmail.com> - 2016-08-04 13:50 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-04 14:20 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Nicholas Piggin <npiggin@gmail.com> - 2016-08-04 14:40 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-04 17:50 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Nicholas Piggin <npiggin@gmail.com> - 2016-08-04 18:10 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-04 18:20 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Segher Boessenkool <segher@kernel.crashing.org> - 2016-08-04 20:30 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Nicholas Piggin <npiggin@gmail.com> - 2016-08-05 10:50 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-05 12:20 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Nicholas Piggin <npiggin@gmail.com> - 2016-08-05 14:30 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-05 18:10 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Nicholas Piggin <npiggin@gmail.com> - 2016-08-05 18:20 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-05 21:20 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Nicholas Piggin <npiggin@gmail.com> - 2016-08-06 22:50 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Arnd Bergmann <arnd@arndb.de> - 2016-08-06 23:20 +0200
Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures Michael Ellerman <mpe@ellerman.id.au> - 2016-08-03 05:30 +0200
Page 1 of 2 [1] 2 Next page →
| From | "Luis R. Rodriguez" <mcgrof@kernel.org> |
|---|---|
| Date | 2016-08-02 22:10 +0200 |
| Subject | powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s1OaK-WW-15@gated-at.bofh.it> |
Are linux-next builds being tested for powerpc with allyesconfig and
allmodconfig ? I have some changes I'm making and while debugging my
build issues I decided to give a clean build a shot and see linux-next
next-20160729 up to next-20160729 all have build failures without my
changes. I get:
/opt/gcc-4.9.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld:
drivers/built-in.o: .opd is not a regular array of opd entries
MODPOST vmlinux.o
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
/opt/gcc-4.9.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld:
drivers/built-in.o: .opd is not a regular array of opd entries
drivers/built-in.o: In function `.ipw2100_up':
ipw2100.c:(.text+0x1ff9c90): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `.round_jiffies_relative' defined
in .text section in kernel/built-in.o
drivers/built-in.o: In function `.ipw2100_reset_adapter':
ipw2100.c:(.text+0x1ffa500): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `._raw_spin_lock_irqsave' defined
in .spinlock.text section in kernel/built-in.o
drivers/built-in.o: In function `.ipw2100_irq_tasklet':
ipw2100.c:(.text+0x1ffa7cc): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `._raw_spin_lock_irqsave' defined
in .spinlock.text section in kernel/built-in.o
ipw2100.c:(.text+0x1ffb6c8): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `.printk' defined in
.text.unlikely section in kernel/built-in.o
ipw2100.c:(.text+0x1ffb6d8): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `.printk' defined in
.text.unlikely section in kernel/built-in.o
ipw2100.c:(.text+0x1ffb740): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `.printk' defined in
.text.unlikely section in kernel/built-in.o
ipw2100.c:(.text+0x1ffb750): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `.printk' defined in
.text.unlikely section in kernel/built-in.o
ipw2100.c:(.text+0x1ffb7ec): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `.debug_dma_unmap_page' defined in
.text section in lib/built-in.o
ipw2100.c:(.text+0x1ffb88c): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `.__dev_kfree_skb_any' defined in
.text section in net/built-in.o
ipw2100.c:(.text+0x1ffb8b8): relocation truncated to fit:
R_PPC64_REL24 (stub) against symbol `.printk' defined in
.text.unlikely section in kernel/built-in.o
ipw2100.c:(.text+0x1ffb8f4): additional relocation overflows omitted
from the output
scripts/link-vmlinux.sh: line 52: 14580 Segmentation fault (core
dumped) ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} -T ${lds}
${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN}
--end-group ${1}
make: *** [Makefile:952: vmlinux] Error 139
Luis
[toc] | [next] | [standalone]
| From | Guenter Roeck <linux@roeck-us.net> |
|---|---|
| Date | 2016-08-03 00:00 +0200 |
| Message-ID | <s1PTc-1PI-9@gated-at.bofh.it> |
| In reply to | #1455443 |
On Tue, Aug 02, 2016 at 01:07:09PM -0700, Luis R. Rodriguez wrote: > Are linux-next builds being tested for powerpc with allyesconfig and > allmodconfig ? I have some changes I'm making and while debugging my > build issues I decided to give a clean build a shot and see linux-next > next-20160729 up to next-20160729 all have build failures without my > changes. I get: > > /opt/gcc-4.9.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: > drivers/built-in.o: .opd is not a regular array of opd entries > MODPOST vmlinux.o > GEN .version > CHK include/generated/compile.h > UPD include/generated/compile.h > CC init/version.o > LD init/built-in.o > /opt/gcc-4.9.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: > drivers/built-in.o: .opd is not a regular array of opd entries > drivers/built-in.o: In function `.ipw2100_up': > ipw2100.c:(.text+0x1ff9c90): relocation truncated to fit: "relocation truncated to fit" errors are typical for ppc:allyesconfig. allmodconfig should work, though. Guenter
[toc] | [prev] | [next] | [standalone]
| From | "Luis R. Rodriguez" <mcgrof@kernel.org> |
|---|---|
| Date | 2016-08-03 00:30 +0200 |
| Message-ID | <s1Qmd-2er-3@gated-at.bofh.it> |
| In reply to | #1455496 |
On Tue, Aug 02, 2016 at 02:58:39PM -0700, Guenter Roeck wrote: > On Tue, Aug 02, 2016 at 01:07:09PM -0700, Luis R. Rodriguez wrote: > > Are linux-next builds being tested for powerpc with allyesconfig and > > allmodconfig ? I have some changes I'm making and while debugging my > > build issues I decided to give a clean build a shot and see linux-next > > next-20160729 up to next-20160729 all have build failures without my > > changes. I get: > > > > /opt/gcc-4.9.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: > > drivers/built-in.o: .opd is not a regular array of opd entries > > MODPOST vmlinux.o > > GEN .version > > CHK include/generated/compile.h > > UPD include/generated/compile.h > > CC init/version.o > > LD init/built-in.o > > /opt/gcc-4.9.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: > > drivers/built-in.o: .opd is not a regular array of opd entries > > drivers/built-in.o: In function `.ipw2100_up': > > ipw2100.c:(.text+0x1ff9c90): relocation truncated to fit: > > "relocation truncated to fit" errors are typical for ppc:allyesconfig. Thanks for the confirmation. For how long is it known this is broken? Does anyone care and fix these ? Or is this best effort? > allmodconfig should work, though. OK thanks. Luis
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-03 00:50 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s1QFz-2lk-9@gated-at.bofh.it> |
| In reply to | #1455506 |
On Wednesday, August 3, 2016 12:02:43 AM CEST Luis R. Rodriguez wrote: > On Tue, Aug 02, 2016 at 02:58:39PM -0700, Guenter Roeck wrote: > > On Tue, Aug 02, 2016 at 01:07:09PM -0700, Luis R. Rodriguez wrote: > > > Are linux-next builds being tested for powerpc with allyesconfig and > > > allmodconfig ? I have some changes I'm making and while debugging my > > > build issues I decided to give a clean build a shot and see linux-next > > > next-20160729 up to next-20160729 all have build failures without my > > > changes. I get: > > > > > > /opt/gcc-4.9.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: > > > drivers/built-in.o: .opd is not a regular array of opd entries > > > MODPOST vmlinux.o > > > GEN .version > > > CHK include/generated/compile.h > > > UPD include/generated/compile.h > > > CC init/version.o > > > LD init/built-in.o > > > /opt/gcc-4.9.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: > > > drivers/built-in.o: .opd is not a regular array of opd entries > > > drivers/built-in.o: In function `.ipw2100_up': > > > ipw2100.c:(.text+0x1ff9c90): relocation truncated to fit: > > > > "relocation truncated to fit" errors are typical for ppc:allyesconfig. > > Thanks for the confirmation. For how long is it known this is broken? > Does anyone care and fix these ? Or is this best effort? We used to have the same thing on ARM, but it's (mostly) fixed now. In case of ARM, the solution was to ensure that all sections that have long jumps or targets of long jumps are marked as executable in the ELF headers, so the linker can insert trampolines. The one remaining problem at the moment is related to recursive linking of the drivers/ directory, which has .text section that is larger than 32MB by itself. There is a patch to solve this by linking each drivers/*/built-in.o object directly into vmlinux, but that is a rather drastic change. Arnd
[toc] | [prev] | [next] | [standalone]
| From | Stephen Rothwell <sfr@canb.auug.org.au> |
|---|---|
| Date | 2016-08-03 02:30 +0200 |
| Message-ID | <s1Sem-3p4-13@gated-at.bofh.it> |
| In reply to | #1455506 |
Hi Luis, On Wed, 3 Aug 2016 00:02:43 +0200 "Luis R. Rodriguez" <mcgrof@kernel.org> wrote: > > Thanks for the confirmation. For how long is it known this is broken? > Does anyone care and fix these ? Or is this best effort? This has been broken for many years :-( I have a couple of times almost fixed it, but it requires that we change from using "ld -r" to build the built-in.o objects and some changes to the powerpc head.S code ... I will give it another shot now that the merge window is almost over (and linux-next goes into its quieter time). -- Cheers, Stephen Rothwell
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-03 10:00 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s1ZfQ-89Q-15@gated-at.bofh.it> |
| In reply to | #1455542 |
On Wednesday, August 3, 2016 10:23:24 AM CEST Stephen Rothwell wrote: > Hi Luis, > > On Wed, 3 Aug 2016 00:02:43 +0200 "Luis R. Rodriguez" <mcgrof@kernel.org> wrote: > > > > Thanks for the confirmation. For how long is it known this is broken? > > Does anyone care and fix these ? Or is this best effort? > > This has been broken for many years > > I have a couple of times almost fixed it, but it requires that we > change from using "ld -r" to build the built-in.o objects and some > changes to the powerpc head.S code ... I will give it another shot now > that the merge window is almost over (and linux-next goes into its > quieter time). Using a different way to link the kernel would also help us with the remaining allyesconfig problem on ARM, as the problem is only in 'ld -r' not producing trampolines for symbols that later cannot get them any more. It would probably also help building with ld.gold, which is currently not working. What is your suggested alternative? Arnd
[toc] | [prev] | [next] | [standalone]
| From | Stephen Rothwell <sfr@canb.auug.org.au> |
|---|---|
| Date | 2016-08-03 14:30 +0200 |
| Message-ID | <s23t7-2tz-1@gated-at.bofh.it> |
| In reply to | #1455671 |
Hi Arnd, On Wed, 03 Aug 2016 09:52:23 +0200 Arnd Bergmann <arnd@arndb.de> wrote: > > Using a different way to link the kernel would also help us with > the remaining allyesconfig problem on ARM, as the problem is only in > 'ld -r' not producing trampolines for symbols that later cannot get > them any more. It would probably also help building with ld.gold, > which is currently not working. > > What is your suggested alternative? I have a patch that make the built-in.o files into thin archives (same as archives, but the actual objects are replaced with the name of the original object file). That way the final link has all the original objects. I haven't checked to see what the overheads of doing it this way is. Nick Piggin has just today taken my old patch (it was last rebased to v4.4-rc1) and tried it on a recent kernel and it still seems to mostly work. It probably needs some tidying up, but you are welcome to test it if you want to. -- Cheers, Stephen Rothwell
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-03 14:40 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s23CN-2wB-11@gated-at.bofh.it> |
| In reply to | #1455778 |
On Wednesday, August 3, 2016 10:19:11 PM CEST Stephen Rothwell wrote: > Hi Arnd, > > On Wed, 03 Aug 2016 09:52:23 +0200 Arnd Bergmann <arnd@arndb.de> wrote: > > > > Using a different way to link the kernel would also help us with > > the remaining allyesconfig problem on ARM, as the problem is only in > > 'ld -r' not producing trampolines for symbols that later cannot get > > them any more. It would probably also help building with ld.gold, > > which is currently not working. > > > > What is your suggested alternative? > > I have a patch that make the built-in.o files into thin archives (same > as archives, but the actual objects are replaced with the name of the > original object file). That way the final link has all the original > objects. I haven't checked to see what the overheads of doing it this > way is. > > Nick Piggin has just today taken my old patch (it was last rebased to > v4.4-rc1) and tried it on a recent kernel and it still seems to mostly > work. It probably needs some tidying up, but you are welcome to test > it if you want to. Sure, I'll certainly give it a try on ARM when you send me a copy. Arnd
[toc] | [prev] | [next] | [standalone]
| From | Nicholas Piggin <npiggin@gmail.com> |
|---|---|
| Date | 2016-08-03 18:00 +0200 |
| Message-ID | <s26Km-4pi-5@gated-at.bofh.it> |
| In reply to | #1455784 |
On Wed, 03 Aug 2016 14:29:13 +0200
Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday, August 3, 2016 10:19:11 PM CEST Stephen Rothwell wrote:
> > Hi Arnd,
> >
> > On Wed, 03 Aug 2016 09:52:23 +0200 Arnd Bergmann <arnd@arndb.de> wrote:
> > >
> > > Using a different way to link the kernel would also help us with
> > > the remaining allyesconfig problem on ARM, as the problem is only in
> > > 'ld -r' not producing trampolines for symbols that later cannot get
> > > them any more. It would probably also help building with ld.gold,
> > > which is currently not working.
> > >
> > > What is your suggested alternative?
> >
> > I have a patch that make the built-in.o files into thin archives (same
> > as archives, but the actual objects are replaced with the name of the
> > original object file). That way the final link has all the original
> > objects. I haven't checked to see what the overheads of doing it this
> > way is.
> >
> > Nick Piggin has just today taken my old patch (it was last rebased to
> > v4.4-rc1) and tried it on a recent kernel and it still seems to mostly
> > work. It probably needs some tidying up, but you are welcome to test
> > it if you want to.
>
> Sure, I'll certainly give it a try on ARM when you send me a copy.
I've attached what I'm using, which builds and runs for me without
any work. Your arch obviously has to select the option to use it.
text data bss dec hex filename
11196784 1185024 1923820 14305628 da495c vmlinuxppc64.before
11187536 1181848 1923176 14292560 da1650 vmlinuxppc64.after
~9K text saving, ~3K data saving. I assume this comes from fewer
branch trampolines and toc entries, but haven't verified exactly.
commit 8bc3ca4798c215e9a9107b6d44408f0af259f84f
Author: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Tue Oct 30 12:14:18 2012 +1100
kbuild: allow architectures to use thin archives instead of ld -r
Alan Modra has been trying to convince the kernel developers that ld -r
is "evil" for many years. This is an alternative and means that the
linker has much more information available to it when it links the
kernel.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
diff --git a/arch/Kconfig b/arch/Kconfig
index d794384..1330bf4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -424,6 +424,12 @@ config CC_STACKPROTECTOR_STRONG
endchoice
+config THIN_ARCHIVES
+ bool
+ help
+ Select this if the architecture wants to use thin archives
+ instead of ld -r to create the built-in.o files.
+
config HAVE_CONTEXT_TRACKING
bool
help
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 0d1ca5b..bbf60b3 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -358,10 +358,15 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ;
# Rule to compile a set of .o files into one .o file
#
ifdef builtin-target
+ifdef CONFIG_THIN_ARCHIVES
+ cmd_make_builtin = rm -f $@; $(AR) rcsT$(KBUILD_ARFLAGS)
+else
+ cmd_make_builtin = $(LD) $(ld_flags) -r -o
+endif
quiet_cmd_link_o_target = LD $@
# If the list of objects to link is empty, just create an empty built-in.o
cmd_link_o_target = $(if $(strip $(obj-y)),\
- $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \
+ $(cmd_make_builtin) $@ $(filter $(obj-y), $^) \
$(cmd_secanalysis),\
rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@)
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index f0f6d9d..ef4658f 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -41,8 +41,14 @@ info()
# ${1} output file
modpost_link()
{
- ${LD} ${LDFLAGS} -r -o ${1} ${KBUILD_VMLINUX_INIT} \
- --start-group ${KBUILD_VMLINUX_MAIN} --end-group
+ local objects
+
+ if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
+ objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
+ else
+ objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
+ fi
+ ${LD} ${LDFLAGS} -r -o ${1} ${objects}
}
# Link of vmlinux
@@ -51,11 +57,16 @@ modpost_link()
vmlinux_link()
{
local lds="${objtree}/${KBUILD_LDS}"
+ local objects
if [ "${SRCARCH}" != "um" ]; then
+ if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
+ objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
+ else
+ objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
+ fi
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
- -T ${lds} ${KBUILD_VMLINUX_INIT} \
- --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1}
+ -T ${lds} ${objects} ${1}
else
${CC} ${CFLAGS_vmlinux} -o ${2} \
-Wl,-T,${lds} ${KBUILD_VMLINUX_INIT} \
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-03 21:10 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s29Ie-6D8-23@gated-at.bofh.it> |
| In reply to | #1455873 |
On Thursday, August 4, 2016 1:37:29 AM CEST Nicholas Piggin wrote: > > I've attached what I'm using, which builds and runs for me without > any work. Your arch obviously has to select the option to use it. > > text data bss dec hex filename > 11196784 1185024 1923820 14305628 da495c vmlinuxppc64.before > 11187536 1181848 1923176 14292560 da1650 vmlinuxppc64.after > > ~9K text saving, ~3K data saving. I assume this comes from fewer > branch trampolines and toc entries, but haven't verified exactly. The patch seems to work great, but for me it's getting bigger (compared to my older patch, mainline allyesconfig doesn't build): text data bss dec hex filename 51299868 42599559 23362148 117261575 6fd4507 vmlinuxarm.before 51302545 42595015 23361884 117259444 6fd3cb4 vmlinuxarm.after Most of the difference appears to be in branch trampolines (634 added, 559 removed, 14837 unchanged) as you suspect, but I also see a couple of symbols show up in vmlinux that were not there before: -A __crc_dma_noop_ops -D dma_noop_ops -R __clz_tab -r fdt_errtable -r __kcrctab_dma_noop_ops -r __kstrtab_dma_noop_ops -R __ksymtab_dma_noop_ops -t dma_noop_alloc -t dma_noop_free -t dma_noop_map_page -t dma_noop_mapping_error -t dma_noop_map_sg -t dma_noop_supported -T fdt_add_reservemap_entry -T fdt_begin_node -T fdt_create -T fdt_create_empty_tree -T fdt_end_node -T fdt_finish -T fdt_finish_reservemap -T fdt_property -T fdt_resize -T fdt_strerror -T find_cpio_data From my first look, it seems that all of lib/*.o is now getting linked into vmlinux, while we traditionally leave out everything from lib/ that is not referenced. I also see a noticeable overhead in link time, the numbers are for a cache-hot rebuild after a successful allyesconfig build, using a 24-way Opteron@2.5Ghz, just relinking vmlinux: $ time make skj30 vmlinux # before real 2m8.092s user 3m41.008s sys 0m48.172s $ time make skj30 vmlinux # after real 4m10.189s user 5m43.804s sys 0m52.988s That is clearly a very sharp difference. Fortunately for the defconfig build, the times are much lower, and I see no real difference other than the noise between subsequent runs: $ time make skj30 vmlinux # before real 0m5.415s user 0m19.716s sys 0m9.356s $ time make skj30 vmlinux # before real 0m9.536s user 0m21.320s sys 0m9.224s $ time make skj30 vmlinux # after real 0m5.539s user 0m20.360s sys 0m9.224s $ time make skj30 vmlinux # after real 0m9.138s user 0m21.932s sys 0m8.988s $ time make skj30 vmlinux # after real 0m5.659s user 0m20.332s sys 0m9.620s Arnd
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-03 22:20 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s2aNY-7my-17@gated-at.bofh.it> |
| In reply to | #1455977 |
On Wednesday, August 3, 2016 2:44:29 PM CEST Segher Boessenkool wrote: > Hi Arnd, > > On Wed, Aug 03, 2016 at 08:52:48PM +0200, Arnd Bergmann wrote: > > From my first look, it seems that all of lib/*.o is now getting linked > > into vmlinux, while we traditionally leave out everything from lib/ > > that is not referenced. > > > > I also see a noticeable overhead in link time, the numbers are for > > a cache-hot rebuild after a successful allyesconfig build, using a > > 24-way Opteron@2.5Ghz, just relinking vmlinux: > > > > $ time make skj30 vmlinux # before > > real 2m8.092s > > user 3m41.008s > > sys 0m48.172s > > > > $ time make skj30 vmlinux # after > > real 4m10.189s > > user 5m43.804s > > sys 0m52.988s > > Is it better when using rcT instead of rcsT? It seems to be noticeably better for the clean rebuild case, though not as good as the original: real 3m34.015s user 5m7.104s sys 0m49.172s I've also tried now with my own patch applied as well (linking each drivers/*/built-in.o into vmlinux rather than having them linked into drivers/built-in.o first), but that makes no difference. Arnd
[toc] | [prev] | [next] | [standalone]
| From | Segher Boessenkool <segher@kernel.crashing.org> |
|---|---|
| Date | 2016-08-03 22:50 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s2aNY-7my-19@gated-at.bofh.it> |
| In reply to | #1455977 |
Hi Arnd, On Wed, Aug 03, 2016 at 08:52:48PM +0200, Arnd Bergmann wrote: > From my first look, it seems that all of lib/*.o is now getting linked > into vmlinux, while we traditionally leave out everything from lib/ > that is not referenced. > > I also see a noticeable overhead in link time, the numbers are for > a cache-hot rebuild after a successful allyesconfig build, using a > 24-way Opteron@2.5Ghz, just relinking vmlinux: > > $ time make skj30 vmlinux # before > real 2m8.092s > user 3m41.008s > sys 0m48.172s > > $ time make skj30 vmlinux # after > real 4m10.189s > user 5m43.804s > sys 0m52.988s Is it better when using rcT instead of rcsT? Segher
[toc] | [prev] | [next] | [standalone]
| From | Stephen Rothwell <sfr@canb.auug.org.au> |
|---|---|
| Date | 2016-08-04 02:20 +0200 |
| Message-ID | <s2eye-1j2-5@gated-at.bofh.it> |
| In reply to | #1455977 |
Hi Arnd,
On Wed, 03 Aug 2016 20:52:48 +0200 Arnd Bergmann <arnd@arndb.de> wrote:
>
> Most of the difference appears to be in branch trampolines (634 added,
> 559 removed, 14837 unchanged) as you suspect, but I also see a couple
> of symbols show up in vmlinux that were not there before:
>
> -A __crc_dma_noop_ops
> -D dma_noop_ops
> -R __clz_tab
> -r fdt_errtable
> -r __kcrctab_dma_noop_ops
> -r __kstrtab_dma_noop_ops
> -R __ksymtab_dma_noop_ops
> -t dma_noop_alloc
> -t dma_noop_free
> -t dma_noop_map_page
> -t dma_noop_mapping_error
> -t dma_noop_map_sg
> -t dma_noop_supported
> -T fdt_add_reservemap_entry
> -T fdt_begin_node
> -T fdt_create
> -T fdt_create_empty_tree
> -T fdt_end_node
> -T fdt_finish
> -T fdt_finish_reservemap
> -T fdt_property
> -T fdt_resize
> -T fdt_strerror
> -T find_cpio_data
>
> From my first look, it seems that all of lib/*.o is now getting linked
> into vmlinux, while we traditionally leave out everything from lib/
> that is not referenced.
You could try removing the --{,no-}whole-archive arguments to ld in
scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh. Last time I did
that, though, a whole lot of stuff failed to be linked in. (Especially
stuff only referenced by EXPORT_SYMBOL()s, bu that may have been fixed).
> I also see a noticeable overhead in link time, the numbers are for
> a cache-hot rebuild after a successful allyesconfig build, using a
> 24-way Opteron@2.5Ghz, just relinking vmlinux:
I was afraid of that, but it is offset by the time saved by not doing
the "ld -r"s along the way? It may also be that (for powerpc anyway)
the linker is doing a better job.
--
Cheers,
Stephen Rothwell
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-04 11:10 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s2mP8-6St-15@gated-at.bofh.it> |
| In reply to | #1456079 |
On Thursday, August 4, 2016 10:10:51 AM CEST Stephen Rothwell wrote:
> Hi Arnd,
>
> On Wed, 03 Aug 2016 20:52:48 +0200 Arnd Bergmann <arnd@arndb.de> wrote:
> >
> > Most of the difference appears to be in branch trampolines (634 added,
> > 559 removed, 14837 unchanged) as you suspect, but I also see a couple
> > of symbols show up in vmlinux that were not there before:
> >
> > -A __crc_dma_noop_ops
> > -D dma_noop_ops
> > -R __clz_tab
> > -r fdt_errtable
> > -r __kcrctab_dma_noop_ops
> > -r __kstrtab_dma_noop_ops
> > -R __ksymtab_dma_noop_ops
> > -t dma_noop_alloc
> > -t dma_noop_free
> > -t dma_noop_map_page
> > -t dma_noop_mapping_error
> > -t dma_noop_map_sg
> > -t dma_noop_supported
> > -T fdt_add_reservemap_entry
> > -T fdt_begin_node
> > -T fdt_create
> > -T fdt_create_empty_tree
> > -T fdt_end_node
> > -T fdt_finish
> > -T fdt_finish_reservemap
> > -T fdt_property
> > -T fdt_resize
> > -T fdt_strerror
> > -T find_cpio_data
> >
> > From my first look, it seems that all of lib/*.o is now getting linked
> > into vmlinux, while we traditionally leave out everything from lib/
> > that is not referenced.
>
> You could try removing the --{,no-}whole-archive arguments to ld in
> scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh. Last time I did
> that, though, a whole lot of stuff failed to be linked in. (Especially
> stuff only referenced by EXPORT_SYMBOL()s, bu that may have been fixed).
I tried this
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index b5e40ed86e60..89bca1a25916 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -44,7 +44,7 @@ modpost_link()
local objects
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
- objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
+ objects="${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
else
objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
fi
but that did not seem to change anything, the extra symbols are
still there. I have not tried to understand what that actually
does, so maybe I misunderstood your suggestion.
> > I also see a noticeable overhead in link time, the numbers are for
> > a cache-hot rebuild after a successful allyesconfig build, using a
> > 24-way Opteron@2.5Ghz, just relinking vmlinux:
>
> I was afraid of that, but it is offset by the time saved by not doing
> the "ld -r"s along the way? It may also be that (for powerpc anyway)
> the linker is doing a better job.
At least on a big SMP system, it doesn't seem to make much difference,
as the "ld -r" steps are easily parallized
$ find build/ -name built-in.o | xargs rm ; time make -skj30 vmlinux
real 2m12.092s
user 3m52.932s
sys 0m51.248s
$ time make -skj30 vmlinux
real 2m12.162s
user 3m44.788s
sys 0m47.788s
I tried this twice with identical results: "user" time increases
by eight seconds today when we have to rebuild all "built-in.o"
files rather than just relinking vmlinux, but elapsed time
is unchanged.
After your patch that difference becomes smaller (three seconds
in one run, could be within the noise), but we still have the
extra two minutes for the total build time:
$ find build/ -name built-in.o | xargs rm ; time make -skj30 vmlinux
real 4m20.717s
user 5m47.556s
sys 0m54.128s
$ time make -skj30 vmlinux
real 4m18.835s
user 5m44.552s
sys 0m53.152s
FWIW, here is a sample build output I get on an allyesconfig build,
with timestamps added:
$ time make W= -kj30 vmlinux
make[1]: Entering directory '/git/arm-soc'
make[2]: Entering directory '/git/arm-soc/build/tmp'
10:46:12 CHK include/config/kernel.release
10:46:13 GEN ./Makefile
10:46:13 CHK include/generated/uapi/linux/version.h
Using /git/arm-soc as source for kernel
10:46:13 CHK include/generated/utsrelease.h
10:46:13 CHK include/generated/timeconst.h
10:46:13 CHK include/generated/bounds.h
10:46:13 CHK include/generated/asm-offsets.h
10:46:13 CALL /git/arm-soc/scripts/checksyscalls.sh
10:46:14 CHK include/generated/compile.h
10:46:18 CHK kernel/config_data.h
10:46:20 CC drivers/misc/lkdtm_rodata.o
10:46:20 OBJCOPY drivers/misc/lkdtm_rodata_objcopy.o
10:46:20 LD drivers/misc/lkdtm.o
10:46:20 LD drivers/misc/built-in.o
10:46:20 DTC drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dtb
10:46:20 DTB drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dtb.S
10:46:20 AS drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dtb.o
10:46:20 LD drivers/gpu/drm/tilcdc/built-in.o
rm drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dtb.S drivers/gpu/drm/tilcdc/tilcdc_slave_compat.dtb
10:46:33 LD drivers/gpu/drm/built-in.o
10:46:33 LD drivers/gpu/built-in.o
10:46:36 CHK include/generated/uapi/linux/version.h
10:46:36 LINK vmlinux
10:46:37 LD vmlinux.o
10:47:14 MODPOST vmlinux.o
10:47:16 GEN .version
10:47:17 CHK include/generated/compile.h
10:47:17 UPD include/generated/compile.h
10:47:17 CC init/version.o
10:47:17 LD init/built-in.o
10:48:09 KSYM .tmp_kallsyms1.o
10:49:19 KSYM .tmp_kallsyms2.o
10:49:33 LD vmlinux
10:50:27 SORTEX vmlinux
10:50:27 SYSMAP System.map
make[2]: Leaving directory '/git/arm-soc/build/tmp'
make[1]: Leaving directory '/git/arm-soc'
real 4m18.033s
user 5m44.728s
sys 0m52.724s
(yes, I also just realized we should fix the tilcdc and lkdtm drivers
to not force a rebuild).
Arnd
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-04 12:50 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s2onT-7Kf-9@gated-at.bofh.it> |
| In reply to | #1456228 |
On Thursday, August 4, 2016 11:00:49 AM CEST Arnd Bergmann wrote:
> I tried this
>
> diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
> index b5e40ed86e60..89bca1a25916 100755
> --- a/scripts/link-vmlinux.sh
> +++ b/scripts/link-vmlinux.sh
> @@ -44,7 +44,7 @@ modpost_link()
> local objects
>
> if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
> - objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
> + objects="${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
> else
> objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
> fi
>
> but that did not seem to change anything, the extra symbols are
> still there. I have not tried to understand what that actually
> does, so maybe I misunderstood your suggestion.
>
On a second attempt, I did the same change for vmlinux instead of the
module (d'oh), and got a link failure instead:
arch/arm/mm/proc-xscale.o: In function `cpu_xscale_do_resume':
(.text+0x3d4): undefined reference to `cpu_resume_mmu'
arch/arm/kernel/setup.o: In function `setup_arch':
setup.c:(.init.text+0x910): undefined reference to `init_uts_ns'
kernel/nsproxy.o:(.data+0x4): undefined reference to `init_uts_ns'
kernel/sched/core.o: In function `update_rq_clock':
core.c:(.text+0x6d8): undefined reference to `paravirt_steal_rq_enabled'
core.c:(.text+0x6dc): undefined reference to `pv_time_ops'
kernel/sched/cputime.o: In function `account_process_tick':
cputime.c:(.text+0x794): undefined reference to `paravirt_steal_enabled'
cputime.c:(.text+0x7a0): undefined reference to `pv_time_ops'
kernel/locking/lockdep.o: In function `save_trace':
lockdep.c:(.text+0xfe8): undefined reference to `save_stack_trace'
kernel/module.o: In function `load_module':
module.c:(.text+0x1b54): undefined reference to `elf_check_arch'
module.c:(.text+0x2024): undefined reference to `apply_relocate'
kernel/debug/debug_core.o: In function `kgdb_unregister_io_module':
debug_core.c:(.text+0x2e4): undefined reference to `kgdb_arch_exit'
kernel/debug/debug_core.o: In function `kgdb_arch_set_breakpoint':
debug_core.c:(.text+0x3bc): undefined reference to `arch_kgdb_ops'
kernel/debug/debug_core.o: In function `dbg_remove_all_break':
debug_core.c:(.text+0x6d0): undefined reference to `arch_kgdb_ops'
...
However, I also see a link failure in some rare configurations
with just your patch:
arch/arm/lib/lib.a(io-acorn.o): In function `outsl':
(.text+0x38): undefined reference to `printk'
The problem being a file in a library object that is not referenced,
but that references another symbol that is not defined
(CONFIG_PRINTK=n).
Arnd
[toc] | [prev] | [next] | [standalone]
| From | Nicholas Piggin <npiggin@gmail.com> |
|---|---|
| Date | 2016-08-04 13:50 +0200 |
| Message-ID | <s2pjY-8pF-7@gated-at.bofh.it> |
| In reply to | #1456324 |
On Thu, 04 Aug 2016 12:37:41 +0200
Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday, August 4, 2016 11:00:49 AM CEST Arnd Bergmann wrote:
> > I tried this
> >
> > diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
> > index b5e40ed86e60..89bca1a25916 100755
> > --- a/scripts/link-vmlinux.sh
> > +++ b/scripts/link-vmlinux.sh
> > @@ -44,7 +44,7 @@ modpost_link()
> > local objects
> >
> > if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
> > - objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
> > + objects="${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
> > else
> > objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
> > fi
> >
> > but that did not seem to change anything, the extra symbols are
> > still there. I have not tried to understand what that actually
> > does, so maybe I misunderstood your suggestion.
> >
>
> On a second attempt, I did the same change for vmlinux instead of the
> module (d'oh), and got a link failure instead:
>
>
> arch/arm/mm/proc-xscale.o: In function `cpu_xscale_do_resume':
> (.text+0x3d4): undefined reference to `cpu_resume_mmu'
> arch/arm/kernel/setup.o: In function `setup_arch':
> setup.c:(.init.text+0x910): undefined reference to `init_uts_ns'
> kernel/nsproxy.o:(.data+0x4): undefined reference to `init_uts_ns'
> kernel/sched/core.o: In function `update_rq_clock':
> core.c:(.text+0x6d8): undefined reference to `paravirt_steal_rq_enabled'
> core.c:(.text+0x6dc): undefined reference to `pv_time_ops'
> kernel/sched/cputime.o: In function `account_process_tick':
> cputime.c:(.text+0x794): undefined reference to `paravirt_steal_enabled'
> cputime.c:(.text+0x7a0): undefined reference to `pv_time_ops'
> kernel/locking/lockdep.o: In function `save_trace':
> lockdep.c:(.text+0xfe8): undefined reference to `save_stack_trace'
> kernel/module.o: In function `load_module':
> module.c:(.text+0x1b54): undefined reference to `elf_check_arch'
> module.c:(.text+0x2024): undefined reference to `apply_relocate'
> kernel/debug/debug_core.o: In function `kgdb_unregister_io_module':
> debug_core.c:(.text+0x2e4): undefined reference to `kgdb_arch_exit'
> kernel/debug/debug_core.o: In function `kgdb_arch_set_breakpoint':
> debug_core.c:(.text+0x3bc): undefined reference to `arch_kgdb_ops'
> kernel/debug/debug_core.o: In function `dbg_remove_all_break':
> debug_core.c:(.text+0x6d0): undefined reference to `arch_kgdb_ops'
> ...
>
> However, I also see a link failure in some rare configurations
> with just your patch:
>
> arch/arm/lib/lib.a(io-acorn.o): In function `outsl':
> (.text+0x38): undefined reference to `printk'
>
> The problem being a file in a library object that is not referenced,
> but that references another symbol that is not defined
> (CONFIG_PRINTK=n).
The first problem is the existing link system is buggy. I think an
unconditional switch to --whole-archive (at least for modular kernels)
should probably be done anyway. For example, on powerpc when building
with --whole-archive, I have:
+dma_noop_alloc
+dma_noop_free
+dma_noop_map_page
+dma_noop_mapping_error
+dma_noop_map_sg
+dma_noop_ops
+dma_noop_supported
+fdt_add_reservemap_entry
+fdt_begin_node
+fdt_create
+fdt_create_empty_tree
+fdt_end_node
+fdt_errtable
+find_cpio_data
+ioremap_page_range
find_cpio_data is unnecessary and it's a codesize regression to link it.
But dma_noop_ops and ioremap_page_range are exported symbols. If I
reference dma_noop_ops from some random module with otherwise unpatched
kernel:
ERROR: "dma_noop_ops" [drivers/char/bsr.ko] undefined!
The real problem is that our linkage requirements are like a shared
library when we build modular.
We could build a list of exports and make it link objects with those
symbols, to solve this, but IMO that's just wasting lipstick on a pig.
But I will to propose a patch to always use --whole-archive, thin
archives or not, and transition all archs over to it in a few release
cycles. It just works by luck right now.
Why is it a pig? Because having the linker to notice no external
references and just skipping the .o completely is trying to use a hammer
as a scalpel. It's just not a very effective way to eliminate dead code
-- I pulled in only a handful of unneeded functions by switching it.
I mean it is a quick simple feature that probably works well enough with
simple build systems. But not an advanced one that builds almost
everything on demand and also has loadable modules and must act like a
shared library.
Real linker DCE is a valid optimisation that can't be replaced by the
build system of course, but we need to do it properly. Here's what I'm
working on.
It applies on top of the previous patch I sent, plus some powerpc stuff
I'm working on that you should be able to just ignore for another arch.
it's a WIP, but if you can see if it works for arm that would be cool.
It doesn't actually build allyesconfig after this,
ld: .tmp_vmlinux1: Too many sections: 220655 (>= 65280)
But on a more reasonable configuration (ppc64le)
text data bss dec filename
11191672 1183536 1923820 14299028 vmlinux
10625528 861895 1919707 13407130 vmlinux.thin+gc
10M-552K 1M-314K ~ 13M-870K
And it actually boots too, which is fairly astounding considering that
it lost half a meg of code and 1/3 of its data. I'm not completely sure
I've not done something wrong...
Thanks,
Nick
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index e75e17c..1594072 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -104,6 +104,10 @@ LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y)
LDFLAGS_vmlinux += --emit-relocs
KBUILD_LDFLAGS_MODULE += --emit-relocs
+KBUILD_CFLAGS += -ffunction-sections -fdata-sections
+LDFLAGS_vmlinux += --gc-sections
+
+
ifeq ($(CONFIG_PPC64),y)
ifeq ($(call cc-option-yn,-mcmodel=medium),y)
# -mcmodel=medium breaks modules because it uses 32bit offsets from
@@ -234,6 +238,8 @@ KBUILD_CFLAGS += $(cpu-as-y)
archscripts: scripts_basic
$(Q)$(MAKE) $(build)=arch/powerpc/tools
+CFLAGS_head_$(CONFIG_WORD_SIZE).o = -fno-function-sections
+
head-y := arch/powerpc/kernel/head_$(CONFIG_WORD_SIZE).o
head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o
head-$(CONFIG_40x) := arch/powerpc/kernel/head_40x.o
@@ -245,6 +251,7 @@ head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
head-$(CONFIG_ALTIVEC) += arch/powerpc/kernel/vector.o
head-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += arch/powerpc/kernel/prom_init.o
+
core-y += arch/powerpc/kernel/ \
arch/powerpc/mm/ \
arch/powerpc/lib/ \
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2da380f..b356e59 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -4,7 +4,10 @@
CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
+ccflags-y += -fno-function-sections -fno-data-sections
+
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+subdir-ccflags-y += -fno-function-sections -fno-data-sections
ifeq ($(CONFIG_PPC64),y)
CFLAGS_prom_init.o += $(NO_MINIMAL_TOC)
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 959c131..0856d62 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -56,16 +56,16 @@ SECTIONS
* in order to optimize stub generation.
*/
.head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
- *(.head.text.first_256B);
+ KEEP(*(.head.text.first_256B));
#ifndef CONFIG_PPC_BOOK3S
. = 0x100;
#else
- *(.head.text.real_vectors);
- *(.head.text.real_trampolines);
- *(.head.text.virt_vectors);
- *(.head.text.virt_trampolines);
+ KEEP(*(.head.text.real_vectors));
+ KEEP(*(.head.text.real_trampolines));
+ KEEP(*(.head.text.virt_vectors));
+ KEEP(*(.head.text.virt_trampolines));
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
- *(.head.data.fwnmi_page);
+ KEEP(*(.head.data.fwnmi_page));
. = 0x8000;
#else
. = 0x7000;
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 6a67ab9..3a35719 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -312,76 +312,76 @@
/* Kernel symbol table: Normal symbols */ \
__ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab) = .; \
- *(SORT(___ksymtab+*)) \
+ KEEP(*(SORT(___ksymtab+*))) \
VMLINUX_SYMBOL(__stop___ksymtab) = .; \
} \
\
/* Kernel symbol table: GPL-only symbols */ \
__ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \
- *(SORT(___ksymtab_gpl+*)) \
+ KEEP(*(SORT(___ksymtab_gpl+*))) \
VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
} \
\
/* Kernel symbol table: Normal unused symbols */ \
__ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \
- *(SORT(___ksymtab_unused+*)) \
+ KEEP(*(SORT(___ksymtab_unused+*))) \
VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \
} \
\
/* Kernel symbol table: GPL-only unused symbols */ \
__ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \
- *(SORT(___ksymtab_unused_gpl+*)) \
+ KEEP(*(SORT(___ksymtab_unused_gpl+*))) \
VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \
} \
\
/* Kernel symbol table: GPL-future-only symbols */ \
__ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \
- *(SORT(___ksymtab_gpl_future+*)) \
+ KEEP(*(SORT(___ksymtab_gpl_future+*))) \
VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \
} \
\
/* Kernel symbol table: Normal symbols */ \
__kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___kcrctab) = .; \
- *(SORT(___kcrctab+*)) \
+ KEEP(*(SORT(___kcrctab+*))) \
VMLINUX_SYMBOL(__stop___kcrctab) = .; \
} \
\
/* Kernel symbol table: GPL-only symbols */ \
__kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \
- *(SORT(___kcrctab_gpl+*)) \
+ KEEP(*(SORT(___kcrctab_gpl+*))) \
VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \
} \
\
/* Kernel symbol table: Normal unused symbols */ \
__kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \
- *(SORT(___kcrctab_unused+*)) \
+ KEEP(*(SORT(___kcrctab_unused+*))) \
VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \
} \
\
/* Kernel symbol table: GPL-only unused symbols */ \
__kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \
- *(SORT(___kcrctab_unused_gpl+*)) \
+ KEEP(*(SORT(___kcrctab_unused_gpl+*))) \
VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \
} \
\
/* Kernel symbol table: GPL-future-only symbols */ \
__kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \
- *(SORT(___kcrctab_gpl_future+*)) \
+ KEEP(*(SORT(___kcrctab_gpl_future+*))) \
VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \
} \
\
/* Kernel symbol table: strings */ \
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
- *(__ksymtab_strings) \
+ KEEP(*(__ksymtab_strings)) \
} \
\
/* __*init sections */ \
@@ -519,6 +519,7 @@
/* init and exit section handling */
#define INIT_DATA \
+ KEEP(*(SORT(___kentry+*))) \
*(.init.data) \
MEM_DISCARD(init.data) \
KERNEL_CTORS() \
@@ -695,9 +696,9 @@
#define INIT_RAM_FS \
. = ALIGN(4); \
VMLINUX_SYMBOL(__initramfs_start) = .; \
- *(.init.ramfs) \
+ KEEP(*(.init.ramfs)) \
. = ALIGN(8); \
- *(.init.ramfs.info)
+ KEEP(*(.init.ramfs.info))
#else
#define INIT_RAM_FS
#endif
diff --git a/include/linux/export.h b/include/linux/export.h
index 2f9ccbe..a921862 100644
--- a/include/linux/export.h
+++ b/include/linux/export.h
@@ -46,7 +46,7 @@ extern struct module __this_module;
extern __visible void *__crc_##sym __attribute__((weak)); \
static const unsigned long __kcrctab_##sym \
__used \
- __attribute__((section("___kcrctab" sec "+" #sym), unused)) \
+ __attribute__((section("___kcrctab" sec "+" #sym ",\"a\",@note #"), used)) \
= (unsigned long) &__crc_##sym;
#else
#define __CRC_SYMBOL(sym, sec)
@@ -57,12 +57,12 @@ extern struct module __this_module;
extern typeof(sym) sym; \
__CRC_SYMBOL(sym, sec) \
static const char __kstrtab_##sym[] \
- __attribute__((section("__ksymtab_strings"), aligned(1))) \
+ __attribute__((section("__ksymtab_strings" ",\"a\",@note #"), aligned(1))) \
= VMLINUX_SYMBOL_STR(sym); \
extern const struct kernel_symbol __ksymtab_##sym; \
__visible const struct kernel_symbol __ksymtab_##sym \
__used \
- __attribute__((section("___ksymtab" sec "+" #sym), unused)) \
+ __attribute__((section("___ksymtab" sec "+" #sym ",\"a\",@note #"), used)) \
= { (unsigned long)&sym, __kstrtab_##sym }
#if defined(__KSYM_DEPS__)
diff --git a/include/linux/init.h b/include/linux/init.h
index aedb254..51393f4 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -156,19 +156,20 @@ extern bool initcall_debug;
#ifndef __ASSEMBLY__
-#ifdef CONFIG_LTO
+#if 1
/* Work around a LTO gcc problem: when there is no reference to a variable
* in a module it will be moved to the end of the program. This causes
* reordering of initcalls which the kernel does not like.
* Add a dummy reference function to avoid this. The function is
* deleted by the linker.
*/
-#define LTO_REFERENCE_INITCALL(x) \
- ; /* yes this is needed */ \
- static __used __exit void *reference_##x(void) \
- { \
- return &x; \
- }
+#define LTO_REFERENCE_INITCALL(sym) \
+ extern typeof(sym) sym; \
+ /* extern const unsigned long __kentry_##sym; */ \
+ static /* __visible */ const unsigned long __kentry_##sym \
+ __used \
+ __attribute__((section("___kentry" "+" #sym ",\"a\",@note #"), used)) \
+ = (unsigned long)&sym;
#else
#define LTO_REFERENCE_INITCALL(x)
#endif
@@ -222,16 +223,18 @@ extern bool initcall_debug;
#define __initcall(fn) device_initcall(fn)
-#define __exitcall(fn) \
- static exitcall_t __exitcall_##fn __exit_call = fn
+#define __exitcall(fn) \
+ static exitcall_t __exitcall_##fn __exit_call = fn; \
-#define console_initcall(fn) \
- static initcall_t __initcall_##fn \
- __used __section(.con_initcall.init) = fn
+#define console_initcall(fn) \
+ static initcall_t __initcall_##fn \
+ __used __section(.con_initcall.init) = fn; \
+ LTO_REFERENCE_INITCALL(__initcall_##fn)
-#define security_initcall(fn) \
- static initcall_t __initcall_##fn \
- __used __section(.security_initcall.init) = fn
+#define security_initcall(fn) \
+ static initcall_t __initcall_##fn \
+ __used __section(.security_initcall.init) = fn; \
+ LTO_REFERENCE_INITCALL(__initcall_##fn)
struct obs_kernel_param {
const char *str;
diff --git a/init/Makefile b/init/Makefile
index 7bc47ee..c4fb455 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -2,6 +2,8 @@
# Makefile for the linux kernel.
#
+ccflags-y := -fno-function-sections -fno-data-sections
+
obj-y := main.o version.o mounts.o
ifneq ($(CONFIG_BLK_DEV_INITRD),y)
obj-y += noinitramfs.o
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index ef4658f..fb848af 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -37,17 +37,22 @@ info()
fi
}
+# Grab all the EXPORT_SYMBOL symbols in the vmlinux build
+# ${1} - output file
+exports_extract()
+{
+ ${NM} -g ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} |
+ grep "R __ksymtab_" |
+ sed 's/.*__ksymtab_\(.*\)$/\1/' > ${1}
+}
+
# Link of vmlinux.o used for section mismatch analysis
# ${1} output file
modpost_link()
{
local objects
- if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
- objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
- else
- objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
- fi
+ objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
${LD} ${LDFLAGS} -r -o ${1} ${objects}
}
@@ -60,11 +65,7 @@ vmlinux_link()
local objects
if [ "${SRCARCH}" != "um" ]; then
- if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
- objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
- else
- objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
- fi
+ objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
-T ${lds} ${objects} ${1}
else
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-04 14:20 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s2pMZ-qc-7@gated-at.bofh.it> |
| In reply to | #1456361 |
On Thursday, August 4, 2016 9:47:13 PM CEST Nicholas Piggin wrote:
> On Thu, 04 Aug 2016 12:37:41 +0200 Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday, August 4, 2016 11:00:49 AM CEST Arnd Bergmann wrote:
> > > I tried this
> > >
> > > diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
> > > index b5e40ed86e60..89bca1a25916 100755
> > > --- a/scripts/link-vmlinux.sh
> > > +++ b/scripts/link-vmlinux.sh
> > > @@ -44,7 +44,7 @@ modpost_link()
> > > local objects
> > >
> > > if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
> > > - objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
> > > + objects="${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
> > > else
> > > objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
> > > fi
> > >
> > > but that did not seem to change anything, the extra symbols are
> > > still there. I have not tried to understand what that actually
> > > does, so maybe I misunderstood your suggestion.
> > >
> >
> > On a second attempt, I did the same change for vmlinux instead of the
> > module (d'oh), and got a link failure instead:
> >
> >
> > arch/arm/mm/proc-xscale.o: In function `cpu_xscale_do_resume':
> > (.text+0x3d4): undefined reference to `cpu_resume_mmu'
> > arch/arm/kernel/setup.o: In function `setup_arch':
> > ...
> >
> > However, I also see a link failure in some rare configurations
> > with just your patch:
> >
> > arch/arm/lib/lib.a(io-acorn.o): In function `outsl':
> > (.text+0x38): undefined reference to `printk'
> >
> > The problem being a file in a library object that is not referenced,
> > but that references another symbol that is not defined
> > (CONFIG_PRINTK=n).
>
> The first problem is the existing link system is buggy. I think an
> unconditional switch to --whole-archive (at least for modular kernels)
> should probably be done anyway. For example, on powerpc when building
> with --whole-archive, I have:
>
> +dma_noop_alloc
> +dma_noop_free
> +dma_noop_map_page
> +dma_noop_mapping_error
> +dma_noop_map_sg
> +dma_noop_ops
> +dma_noop_supported
> +fdt_add_reservemap_entry
> +fdt_begin_node
> +fdt_create
> +fdt_create_empty_tree
> +fdt_end_node
> +fdt_errtable
> +find_cpio_data
> +ioremap_page_range
>
> find_cpio_data is unnecessary and it's a codesize regression to link it.
> But dma_noop_ops and ioremap_page_range are exported symbols. If I
> reference dma_noop_ops from some random module with otherwise unpatched
> kernel:
>
> ERROR: "dma_noop_ops" [drivers/char/bsr.ko] undefined!
Right, but only on s390, which is the one architecture using this.
I think we should just have a Kconfig symbol for this file that
gets selected by any architecture that needs it.
This is also what we have ended up doing for almost all other
files in lib/
> The real problem is that our linkage requirements are like a shared
> library when we build modular.
>
> We could build a list of exports and make it link objects with those
> symbols, to solve this, but IMO that's just wasting lipstick on a pig.
> But I will to propose a patch to always use --whole-archive, thin
> archives or not, and transition all archs over to it in a few release
> cycles. It just works by luck right now.
>
> Why is it a pig? Because having the linker to notice no external
> references and just skipping the .o completely is trying to use a hammer
> as a scalpel. It's just not a very effective way to eliminate dead code
> -- I pulled in only a handful of unneeded functions by switching it.
If we do that, we may just as well get rid of $(lib-y) in the process and
always use $(obj-y).
> I mean it is a quick simple feature that probably works well enough with
> simple build systems. But not an advanced one that builds almost
> everything on demand and also has loadable modules and must act like a
> shared library.
>
> Real linker DCE is a valid optimisation that can't be replaced by the
> build system of course, but we need to do it properly. Here's what I'm
> working on.
>
> It applies on top of the previous patch I sent, plus some powerpc stuff
> I'm working on that you should be able to just ignore for another arch.
> it's a WIP, but if you can see if it works for arm that would be cool.
>
> It doesn't actually build allyesconfig after this,
> ld: .tmp_vmlinux1: Too many sections: 220655 (>= 65280)
>
> But on a more reasonable configuration (ppc64le)
> text data bss dec filename
> 11191672 1183536 1923820 14299028 vmlinux
> 10625528 861895 1919707 13407130 vmlinux.thin+gc
>
> 10M-552K 1M-314K ~ 13M-870K
Nice!
> And it actually boots too, which is fairly astounding considering that
> it lost half a meg of code and 1/3 of its data. I'm not completely sure
> I've not done something wrong...
Nicolas Pitre has done some related work, adding him to Cc. IIRC we have
actually had multiple implementations of -ffunction-sections/--gc-sections
in the past that people have used in production, but none of them
ever made it upstream.
One question is whether we should bother with --gc-sections at all,
or use full LTO instead.
Arnd
---
(full patch quoted below for Nico, no further comments)
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index e75e17c..1594072 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -104,6 +104,10 @@ LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y)
> LDFLAGS_vmlinux += --emit-relocs
> KBUILD_LDFLAGS_MODULE += --emit-relocs
>
> +KBUILD_CFLAGS += -ffunction-sections -fdata-sections
> +LDFLAGS_vmlinux += --gc-sections
> +
> +
> ifeq ($(CONFIG_PPC64),y)
> ifeq ($(call cc-option-yn,-mcmodel=medium),y)
> # -mcmodel=medium breaks modules because it uses 32bit offsets from
> @@ -234,6 +238,8 @@ KBUILD_CFLAGS += $(cpu-as-y)
> archscripts: scripts_basic
> $(Q)$(MAKE) $(build)=arch/powerpc/tools
>
> +CFLAGS_head_$(CONFIG_WORD_SIZE).o = -fno-function-sections
> +
> head-y := arch/powerpc/kernel/head_$(CONFIG_WORD_SIZE).o
> head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o
> head-$(CONFIG_40x) := arch/powerpc/kernel/head_40x.o
> @@ -245,6 +251,7 @@ head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
> head-$(CONFIG_ALTIVEC) += arch/powerpc/kernel/vector.o
> head-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += arch/powerpc/kernel/prom_init.o
>
> +
> core-y += arch/powerpc/kernel/ \
> arch/powerpc/mm/ \
> arch/powerpc/lib/ \
> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
> index 2da380f..b356e59 100644
> --- a/arch/powerpc/kernel/Makefile
> +++ b/arch/powerpc/kernel/Makefile
> @@ -4,7 +4,10 @@
>
> CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
>
> +ccflags-y += -fno-function-sections -fno-data-sections
> +
> subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
> +subdir-ccflags-y += -fno-function-sections -fno-data-sections
>
> ifeq ($(CONFIG_PPC64),y)
> CFLAGS_prom_init.o += $(NO_MINIMAL_TOC)
> diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
> index 959c131..0856d62 100644
> --- a/arch/powerpc/kernel/vmlinux.lds.S
> +++ b/arch/powerpc/kernel/vmlinux.lds.S
> @@ -56,16 +56,16 @@ SECTIONS
> * in order to optimize stub generation.
> */
> .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
> - *(.head.text.first_256B);
> + KEEP(*(.head.text.first_256B));
> #ifndef CONFIG_PPC_BOOK3S
> . = 0x100;
> #else
> - *(.head.text.real_vectors);
> - *(.head.text.real_trampolines);
> - *(.head.text.virt_vectors);
> - *(.head.text.virt_trampolines);
> + KEEP(*(.head.text.real_vectors));
> + KEEP(*(.head.text.real_trampolines));
> + KEEP(*(.head.text.virt_vectors));
> + KEEP(*(.head.text.virt_trampolines));
> #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
> - *(.head.data.fwnmi_page);
> + KEEP(*(.head.data.fwnmi_page));
> . = 0x8000;
> #else
> . = 0x7000;
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index 6a67ab9..3a35719 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -312,76 +312,76 @@
> /* Kernel symbol table: Normal symbols */ \
> __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___ksymtab) = .; \
> - *(SORT(___ksymtab+*)) \
> + KEEP(*(SORT(___ksymtab+*))) \
> VMLINUX_SYMBOL(__stop___ksymtab) = .; \
> } \
> \
> /* Kernel symbol table: GPL-only symbols */ \
> __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \
> - *(SORT(___ksymtab_gpl+*)) \
> + KEEP(*(SORT(___ksymtab_gpl+*))) \
> VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
> } \
> \
> /* Kernel symbol table: Normal unused symbols */ \
> __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \
> - *(SORT(___ksymtab_unused+*)) \
> + KEEP(*(SORT(___ksymtab_unused+*))) \
> VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \
> } \
> \
> /* Kernel symbol table: GPL-only unused symbols */ \
> __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \
> - *(SORT(___ksymtab_unused_gpl+*)) \
> + KEEP(*(SORT(___ksymtab_unused_gpl+*))) \
> VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \
> } \
> \
> /* Kernel symbol table: GPL-future-only symbols */ \
> __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \
> - *(SORT(___ksymtab_gpl_future+*)) \
> + KEEP(*(SORT(___ksymtab_gpl_future+*))) \
> VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \
> } \
> \
> /* Kernel symbol table: Normal symbols */ \
> __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___kcrctab) = .; \
> - *(SORT(___kcrctab+*)) \
> + KEEP(*(SORT(___kcrctab+*))) \
> VMLINUX_SYMBOL(__stop___kcrctab) = .; \
> } \
> \
> /* Kernel symbol table: GPL-only symbols */ \
> __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \
> - *(SORT(___kcrctab_gpl+*)) \
> + KEEP(*(SORT(___kcrctab_gpl+*))) \
> VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \
> } \
> \
> /* Kernel symbol table: Normal unused symbols */ \
> __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \
> - *(SORT(___kcrctab_unused+*)) \
> + KEEP(*(SORT(___kcrctab_unused+*))) \
> VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \
> } \
> \
> /* Kernel symbol table: GPL-only unused symbols */ \
> __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \
> - *(SORT(___kcrctab_unused_gpl+*)) \
> + KEEP(*(SORT(___kcrctab_unused_gpl+*))) \
> VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \
> } \
> \
> /* Kernel symbol table: GPL-future-only symbols */ \
> __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
> VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \
> - *(SORT(___kcrctab_gpl_future+*)) \
> + KEEP(*(SORT(___kcrctab_gpl_future+*))) \
> VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \
> } \
> \
> /* Kernel symbol table: strings */ \
> __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
> - *(__ksymtab_strings) \
> + KEEP(*(__ksymtab_strings)) \
> } \
> \
> /* __*init sections */ \
> @@ -519,6 +519,7 @@
>
> /* init and exit section handling */
> #define INIT_DATA \
> + KEEP(*(SORT(___kentry+*))) \
> *(.init.data) \
> MEM_DISCARD(init.data) \
> KERNEL_CTORS() \
> @@ -695,9 +696,9 @@
> #define INIT_RAM_FS \
> . = ALIGN(4); \
> VMLINUX_SYMBOL(__initramfs_start) = .; \
> - *(.init.ramfs) \
> + KEEP(*(.init.ramfs)) \
> . = ALIGN(8); \
> - *(.init.ramfs.info)
> + KEEP(*(.init.ramfs.info))
> #else
> #define INIT_RAM_FS
> #endif
> diff --git a/include/linux/export.h b/include/linux/export.h
> index 2f9ccbe..a921862 100644
> --- a/include/linux/export.h
> +++ b/include/linux/export.h
> @@ -46,7 +46,7 @@ extern struct module __this_module;
> extern __visible void *__crc_##sym __attribute__((weak)); \
> static const unsigned long __kcrctab_##sym \
> __used \
> - __attribute__((section("___kcrctab" sec "+" #sym), unused)) \
> + __attribute__((section("___kcrctab" sec "+" #sym ",\"a\",@note #"), used)) \
> = (unsigned long) &__crc_##sym;
> #else
> #define __CRC_SYMBOL(sym, sec)
> @@ -57,12 +57,12 @@ extern struct module __this_module;
> extern typeof(sym) sym; \
> __CRC_SYMBOL(sym, sec) \
> static const char __kstrtab_##sym[] \
> - __attribute__((section("__ksymtab_strings"), aligned(1))) \
> + __attribute__((section("__ksymtab_strings" ",\"a\",@note #"), aligned(1))) \
> = VMLINUX_SYMBOL_STR(sym); \
> extern const struct kernel_symbol __ksymtab_##sym; \
> __visible const struct kernel_symbol __ksymtab_##sym \
> __used \
> - __attribute__((section("___ksymtab" sec "+" #sym), unused)) \
> + __attribute__((section("___ksymtab" sec "+" #sym ",\"a\",@note #"), used)) \
> = { (unsigned long)&sym, __kstrtab_##sym }
>
> #if defined(__KSYM_DEPS__)
> diff --git a/include/linux/init.h b/include/linux/init.h
> index aedb254..51393f4 100644
> --- a/include/linux/init.h
> +++ b/include/linux/init.h
> @@ -156,19 +156,20 @@ extern bool initcall_debug;
>
> #ifndef __ASSEMBLY__
>
> -#ifdef CONFIG_LTO
> +#if 1
> /* Work around a LTO gcc problem: when there is no reference to a variable
> * in a module it will be moved to the end of the program. This causes
> * reordering of initcalls which the kernel does not like.
> * Add a dummy reference function to avoid this. The function is
> * deleted by the linker.
> */
> -#define LTO_REFERENCE_INITCALL(x) \
> - ; /* yes this is needed */ \
> - static __used __exit void *reference_##x(void) \
> - { \
> - return &x; \
> - }
> +#define LTO_REFERENCE_INITCALL(sym) \
> + extern typeof(sym) sym; \
> + /* extern const unsigned long __kentry_##sym; */ \
> + static /* __visible */ const unsigned long __kentry_##sym \
> + __used \
> + __attribute__((section("___kentry" "+" #sym ",\"a\",@note #"), used)) \
> + = (unsigned long)&sym;
> #else
> #define LTO_REFERENCE_INITCALL(x)
> #endif
> @@ -222,16 +223,18 @@ extern bool initcall_debug;
>
> #define __initcall(fn) device_initcall(fn)
>
> -#define __exitcall(fn) \
> - static exitcall_t __exitcall_##fn __exit_call = fn
> +#define __exitcall(fn) \
> + static exitcall_t __exitcall_##fn __exit_call = fn; \
>
> -#define console_initcall(fn) \
> - static initcall_t __initcall_##fn \
> - __used __section(.con_initcall.init) = fn
> +#define console_initcall(fn) \
> + static initcall_t __initcall_##fn \
> + __used __section(.con_initcall.init) = fn; \
> + LTO_REFERENCE_INITCALL(__initcall_##fn)
>
> -#define security_initcall(fn) \
> - static initcall_t __initcall_##fn \
> - __used __section(.security_initcall.init) = fn
> +#define security_initcall(fn) \
> + static initcall_t __initcall_##fn \
> + __used __section(.security_initcall.init) = fn; \
> + LTO_REFERENCE_INITCALL(__initcall_##fn)
>
> struct obs_kernel_param {
> const char *str;
> diff --git a/init/Makefile b/init/Makefile
> index 7bc47ee..c4fb455 100644
> --- a/init/Makefile
> +++ b/init/Makefile
> @@ -2,6 +2,8 @@
> # Makefile for the linux kernel.
> #
>
> +ccflags-y := -fno-function-sections -fno-data-sections
> +
> obj-y := main.o version.o mounts.o
> ifneq ($(CONFIG_BLK_DEV_INITRD),y)
> obj-y += noinitramfs.o
> diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
> index ef4658f..fb848af 100755
> --- a/scripts/link-vmlinux.sh
> +++ b/scripts/link-vmlinux.sh
> @@ -37,17 +37,22 @@ info()
> fi
> }
>
> +# Grab all the EXPORT_SYMBOL symbols in the vmlinux build
> +# ${1} - output file
> +exports_extract()
> +{
> + ${NM} -g ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} |
> + grep "R __ksymtab_" |
> + sed 's/.*__ksymtab_\(.*\)$/\1/' > ${1}
> +}
> +
> # Link of vmlinux.o used for section mismatch analysis
> # ${1} output file
> modpost_link()
> {
> local objects
>
> - if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
> - objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
> - else
> - objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
> - fi
> + objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
> ${LD} ${LDFLAGS} -r -o ${1} ${objects}
> }
>
> @@ -60,11 +65,7 @@ vmlinux_link()
> local objects
>
> if [ "${SRCARCH}" != "um" ]; then
> - if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
> - objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
> - else
> - objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
> - fi
> + objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
> ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
> -T ${lds} ${objects} ${1}
> else
>
[toc] | [prev] | [next] | [standalone]
| From | Nicholas Piggin <npiggin@gmail.com> |
|---|---|
| Date | 2016-08-04 14:40 +0200 |
| Message-ID | <s2q6m-DV-27@gated-at.bofh.it> |
| In reply to | #1456364 |
On Thu, 04 Aug 2016 14:09:02 +0200
Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday, August 4, 2016 9:47:13 PM CEST Nicholas Piggin wrote:
> > On Thu, 04 Aug 2016 12:37:41 +0200 Arnd Bergmann <arnd@arndb.de> wrote:
> > > On Thursday, August 4, 2016 11:00:49 AM CEST Arnd Bergmann wrote:
> > > > I tried this
> > > >
> > > > diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
> > > > index b5e40ed86e60..89bca1a25916 100755
> > > > --- a/scripts/link-vmlinux.sh
> > > > +++ b/scripts/link-vmlinux.sh
> > > > @@ -44,7 +44,7 @@ modpost_link()
> > > > local objects
> > > >
> > > > if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
> > > > - objects="--whole-archive ${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN} --no-whole-archive"
> > > > + objects="${KBUILD_VMLINUX_INIT} ${KBUILD_VMLINUX_MAIN}"
> > > > else
> > > > objects="${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group"
> > > > fi
> > > >
> > > > but that did not seem to change anything, the extra symbols are
> > > > still there. I have not tried to understand what that actually
> > > > does, so maybe I misunderstood your suggestion.
> > > >
> > >
> > > On a second attempt, I did the same change for vmlinux instead of the
> > > module (d'oh), and got a link failure instead:
> > >
> > >
> > > arch/arm/mm/proc-xscale.o: In function `cpu_xscale_do_resume':
> > > (.text+0x3d4): undefined reference to `cpu_resume_mmu'
> > > arch/arm/kernel/setup.o: In function `setup_arch':
> > > ...
> > >
> > > However, I also see a link failure in some rare configurations
> > > with just your patch:
> > >
> > > arch/arm/lib/lib.a(io-acorn.o): In function `outsl':
> > > (.text+0x38): undefined reference to `printk'
> > >
> > > The problem being a file in a library object that is not referenced,
> > > but that references another symbol that is not defined
> > > (CONFIG_PRINTK=n).
> >
> > The first problem is the existing link system is buggy. I think an
> > unconditional switch to --whole-archive (at least for modular kernels)
> > should probably be done anyway. For example, on powerpc when building
> > with --whole-archive, I have:
> >
> > +dma_noop_alloc
> > +dma_noop_free
> > +dma_noop_map_page
> > +dma_noop_mapping_error
> > +dma_noop_map_sg
> > +dma_noop_ops
> > +dma_noop_supported
> > +fdt_add_reservemap_entry
> > +fdt_begin_node
> > +fdt_create
> > +fdt_create_empty_tree
> > +fdt_end_node
> > +fdt_errtable
> > +find_cpio_data
> > +ioremap_page_range
> >
> > find_cpio_data is unnecessary and it's a codesize regression to link it.
> > But dma_noop_ops and ioremap_page_range are exported symbols. If I
> > reference dma_noop_ops from some random module with otherwise unpatched
> > kernel:
> >
> > ERROR: "dma_noop_ops" [drivers/char/bsr.ko] undefined!
>
> Right, but only on s390, which is the one architecture using this.
> I think we should just have a Kconfig symbol for this file that
> gets selected by any architecture that needs it.
No, the problem is that the module is being selected and built
but it is missing from the vmlinux despite being exported.
> This is also what we have ended up doing for almost all other
> files in lib/
>
> > The real problem is that our linkage requirements are like a shared
> > library when we build modular.
> >
> > We could build a list of exports and make it link objects with those
> > symbols, to solve this, but IMO that's just wasting lipstick on a pig.
> > But I will to propose a patch to always use --whole-archive, thin
> > archives or not, and transition all archs over to it in a few release
> > cycles. It just works by luck right now.
> >
> > Why is it a pig? Because having the linker to notice no external
> > references and just skipping the .o completely is trying to use a hammer
> > as a scalpel. It's just not a very effective way to eliminate dead code
> > -- I pulled in only a handful of unneeded functions by switching it.
>
> If we do that, we may just as well get rid of $(lib-y) in the process and
> always use $(obj-y).
Sure, after we switch everybody over.
> > I mean it is a quick simple feature that probably works well enough with
> > simple build systems. But not an advanced one that builds almost
> > everything on demand and also has loadable modules and must act like a
> > shared library.
> >
> > Real linker DCE is a valid optimisation that can't be replaced by the
> > build system of course, but we need to do it properly. Here's what I'm
> > working on.
> >
> > It applies on top of the previous patch I sent, plus some powerpc stuff
> > I'm working on that you should be able to just ignore for another arch.
> > it's a WIP, but if you can see if it works for arm that would be cool.
> >
> > It doesn't actually build allyesconfig after this,
> > ld: .tmp_vmlinux1: Too many sections: 220655 (>= 65280)
> >
> > But on a more reasonable configuration (ppc64le)
> > text data bss dec filename
> > 11191672 1183536 1923820 14299028 vmlinux
> > 10625528 861895 1919707 13407130 vmlinux.thin+gc
> >
> > 10M-552K 1M-314K ~ 13M-870K
>
> Nice!
>
> > And it actually boots too, which is fairly astounding considering that
> > it lost half a meg of code and 1/3 of its data. I'm not completely sure
> > I've not done something wrong...
>
> Nicolas Pitre has done some related work, adding him to Cc. IIRC we have
> actually had multiple implementations of -ffunction-sections/--gc-sections
> in the past that people have used in production, but none of them
> ever made it upstream.
Well I'll try to get it upstream for powerpc so that Stephen's thin ar
patch does not cause a regression. I don't see the problem -- except
with huge configs (that don't build with mainline powerpc anyway), but
it could be an option for build testers who want to do all(yes|mod)config
> One question is whether we should bother with --gc-sections at all,
> or use full LTO instead.
It's no bother. I'm not even sure lto is a complete superset of
ffunction-sections/gc-sections, but either way it is a huge change to
the build and toolchain, whereas gc sections is relatively unremarkable.
Lto is very interesting but will take a big effort to implement and
prove itself I think.
Thanks,
Nick
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-08-04 17:50 +0200 |
| Subject | Re: powerpc allyesconfig / allmodconfig linux-next next-20160729 - next-20160729 build failures |
| Message-ID | <s2t4e-2PF-27@gated-at.bofh.it> |
| In reply to | #1456377 |
On Thursday, August 4, 2016 11:54:18 PM CEST Nicholas Piggin wrote: > On Thu, 4 Aug 2016 22:31:39 +1000 > Nicholas Piggin <npiggin@gmail.com> wrote: > > On Thu, 04 Aug 2016 14:09:02 +0200 > > Arnd Bergmann <arnd@arndb.de> wrote: > > > Nicolas Pitre has done some related work, adding him to Cc. IIRC we have > > > actually had multiple implementations of -ffunction-sections/--gc-sections > > > in the past that people have used in production, but none of them > > > ever made it upstream. > > After some googling around it seems lto has been difficult to > get in and it was agreed this gc-sections should be done first > anyway (although it may indeed provide a superset of DCE, but > it's always going to be more costly and complicated). Lto would > have the same issue with liveness of entry points, which is > really the only thing you need change in the kernel as far as I > can see. Ok, good. > I didn't really see what problems people were having with it > though, so maybe it's architecture specific or something I > haven't run into yet. I remember trying it a few years ago without success, it's possible that old binutils versions were more problematic. I'm happy to test your patches on ARM, with my randconfig builder I tend to find obscure bugs in corner cases that you might not normally find with just defconfig/allmodconfig builds. Arnd
[toc] | [prev] | [next] | [standalone]
| From | Nicholas Piggin <npiggin@gmail.com> |
|---|---|
| Date | 2016-08-04 18:10 +0200 |
| Message-ID | <s2t4e-2PF-29@gated-at.bofh.it> |
| In reply to | #1456377 |
On Thu, 4 Aug 2016 22:31:39 +1000 Nicholas Piggin <npiggin@gmail.com> wrote: > On Thu, 04 Aug 2016 14:09:02 +0200 > Arnd Bergmann <arnd@arndb.de> wrote: > > Nicolas Pitre has done some related work, adding him to Cc. IIRC we have > > actually had multiple implementations of -ffunction-sections/--gc-sections > > in the past that people have used in production, but none of them > > ever made it upstream. After some googling around it seems lto has been difficult to get in and it was agreed this gc-sections should be done first anyway (although it may indeed provide a superset of DCE, but it's always going to be more costly and complicated). Lto would have the same issue with liveness of entry points, which is really the only thing you need change in the kernel as far as I can see. I didn't really see what problems people were having with it though, so maybe it's architecture specific or something I haven't run into yet. Thanks, Nick
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web