A kernel build consists of more than one linking pass on vmlinux.o and
vmlinux, at minimum two, and with CONFIG_KALLSYMS and BTF enabled on x86-64
for example there are 5 such stages.

For architectures that build their own relocation tables (x86, riscv, mips,
s390), vmlinux is linked with the --emit-relocs parameter specified.

However, this is only required on the final vmlinux link.

Symbol tables of trial links preceding it don't need it because they
already check that System.map matches kallsyms symbols on each build.

GNU ld is slow at emitting relocation tables, so this results in a
reduction in build time.

Whole build, 128-thread Threadripper 9980X, best of N runs:

                                         before   after     delta
                                         -------------------------------
  x86 defconfig, touch mm/vma.c, gcc        9.5s     9.1s    -0.42s (-4%)
  x86 defconfig, clean, gcc                30.1s    29.5s    -0.59s (-2%)
  x86 allmodconfig, touch mm/vma.c, gcc    37.2s    35.8s     -1.4s (-4%)

Note that this has little impact on LLVM ld which performs this operation
more efficiently.

Assisted-by: LLM
Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
---
 Makefile                | 2 +-
 scripts/link-vmlinux.sh | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 0f1b80100b47..dd4c10afbb7f 100644
--- a/Makefile
+++ b/Makefile
@@ -1263,7 +1263,7 @@ LDFLAGS_vmlinux += 
--orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
 endif
 
 ifneq ($(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS),)
-LDFLAGS_vmlinux        += --emit-relocs --discard-none
+LDFLAGS_vmlinux        += --discard-none
 endif
 
 # Align the architecture of userspace programs with the kernel
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 970ca10f8fa9..ed5ff97c0667 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -96,6 +96,11 @@ vmlinux_link()
                ldflags="${ldflags} ${wl}--strip-debug"
        fi
 
+       # Only the final link actually requires the relocations.
+       if [ "${output}" = "${VMLINUX}" ] && is_enabled 
CONFIG_ARCH_VMLINUX_NEEDS_RELOCS; then
+               ldflags="${ldflags} ${wl}--emit-relocs"
+       fi
+
        if [ -n "${generate_map}" ];  then
                ldflags="${ldflags} ${wl}-Map=vmlinux.map"
        fi

-- 
2.55.0


Reply via email to