Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

excessive slowdown linking RISCV with --gc-sections #1881

Open
nickdesaulniers opened this issue Jun 23, 2023 · 6 comments
Open

excessive slowdown linking RISCV with --gc-sections #1881

nickdesaulniers opened this issue Jun 23, 2023 · 6 comments
Labels
[ARCH] risc-v This bug impacts ARCH=riscv [TOOL] lld The issue is relevant to LLD linker

Comments

@nickdesaulniers
Copy link
Member

Reported-by: Palmer Dabbelt palmer@dabbelt.com
via: https://lore.kernel.org/linux-riscv/mhng-57559277-afaa-4a85-a3ad-b9be6dba737f@palmer-ri-x1c9/

If I apply that patchset to mainline, then build allyesconfig, it seems to take hours to link the RISCV kernel.

$ ARCH=riscv LLVM=1 make -j128 vmlinux

$ perf record -e cycles ld.lld -melf64lriscv -z noexecstack -r -o vmlinux.o  --whole-archive vmlinux.a --no-whole-archive --start-group ./drivers/firmware/efi/libstub/lib.a --end-group
$ perf report --no-children --sort=dso,symbol
Overhead  Shared Object         Symbol
  61.64%  lld                   [.] lld::elf::LinkerScript::addOrphanSections()::$_0::operator()
  34.63%  lld                   [.] lld::elf::InputSectionBase::getLinkOrderDep
   3.00%  lld                   [.] lld::elf::SectionBase::getOutputSection
   0.05%  libc.so.6             [.] __strlen_avx2

@nathanchance suggested adding a patch on top:

diff --git a/init/Kconfig b/init/Kconfig
index 32c24950c4ce..25434cbd2a6e 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1388,7 +1388,7 @@ config HAVE_LD_DEAD_CODE_DATA_ELIMINATION
 config LD_DEAD_CODE_DATA_ELIMINATION
 	bool "Dead code and data elimination (EXPERIMENTAL)"
 	depends on HAVE_LD_DEAD_CODE_DATA_ELIMINATION
-	depends on EXPERT
+	depends on EXPERT && !COMPILE_TEST
 	depends on $(cc-option,-ffunction-sections -fdata-sections)
 	depends on $(ld-option,--gc-sections)
 	help

or:

If you wanted to restrict it to just LD_IS_BFD in arch/riscv/Kconfig,
that would be fine with me too.

  select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if LD_IS_BFD

cc @palmer-dabbelt @MaskRay @nathanchance

@nickdesaulniers nickdesaulniers added [TOOL] lld The issue is relevant to LLD linker [ARCH] risc-v This bug impacts ARCH=riscv labels Jun 23, 2023
@palmer-dabbelt
Copy link

I'm fine taking the !COMPILE_TEST (or whatever keep this out of allyesconfig and randconfig and such). Having it as narrow as we can seems like the way to go, so if this is RISC-V and LLD only then I'm happy to take something specific to those (or whatever subset is slow).

@nickdesaulniers
Copy link
Member Author

@nickdesaulniers
Copy link
Member Author

FWIW, just logging what the "orphan sections" are:

diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 777f1f2f85f9..958e926042fb 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -823,6 +823,7 @@ void LinkerScript::addOrphanSections() {
   auto add = [&](InputSectionBase *s) {
     if (s->isLive() && !s->parent) {
       orphanSections.push_back(s);
+      llvm::errs() << "XXX: " << s->name << "\n";
 
       StringRef name = getOutputSectionName(s);
       if (config->unique) {

produces a repeating spew of:

...
XXX: .text
XXX: .sdata
XXX: .text.squashfs_frag_lookup
XXX: __patchable_function_entries
XXX: .rela.text.squashfs_frag_lookup
XXX: .rela__patchable_function_entries
XXX: .text.squashfs_read_fragment_index_table
XXX: __patchable_function_entries
XXX: .rela.text.squashfs_read_fragment_index_table
XXX: .rela__patchable_function_entries
XXX: .comment
XXX: .llvm_addrsig
XXX: .text
XXX: .text.squashfs_get_id
XXX: __patchable_function_entries
XXX: .rela.text.squashfs_get_id
XXX: .rela__patchable_function_entries
XXX: .text.squashfs_read_id_index_table
XXX: __patchable_function_entries
XXX: .rela.text.squashfs_read_id_index_table
XXX: __jump_table
XXX: .rela__jump_table
XXX: .rela__patchable_function_entries
XXX: __dyndbg
XXX: .rela__dyndbg
XXX: .rodata.str1.1
XXX: .comment
XXX: .llvm_addrsig
XXX: .text
XXX: .text.squashfs_iget
XXX: __patchable_function_entries
XXX: .rela.text.squashfs_iget
XXX: __jump_table
XXX: .rela__jump_table
XXX: .rela__patchable_function_entries
XXX: .sdata
XXX: .text.squashfs_read_inode
XXX: __patchable_function_entries
XXX: .rela.text.squashfs_read_inode
XXX: .rodata.squashfs_read_inode
XXX: .rela.rodata.squashfs_read_inode
XXX: .rela__patchable_function_entries
XXX: __dyndbg
XXX: .rela__dyndbg
XXX: .rodata.str1.1
...

@nickdesaulniers
Copy link
Member Author

arch/riscv/Kconfig
52:	select ARCH_WANT_LD_ORPHAN_WARN if !XIP_KERNEL

So we should be setting --orphan-handling=warn; we're not seeing any warnings, so I'm surprised we're spending so much time processing orphan sections. Perhaps the above list aren't orphans, and LLD is misdiagnosing them as such?

@palmer-dabbelt
Copy link

Sent: https://lore.kernel.org/linux-riscv/ZJXTwqZIkXLxXaSi@google.com/

Thanks. I'm trying to sort out some other issue in my staging tree so it might take a bit to get to, but I'll be working this weekend either way so it shouldn't be too long.

prabhakarlad pushed a commit to prabhakarlad/linux that referenced this issue Jun 30, 2023
Linking allyesconfig with ld.lld-17 with CONFIG_DEAD_CODE_ELIMINATION=y
takes hours.  Assuming this is a performance regression that can be
fixed, tentatively disable this for now so that allyesconfig builds
don't start timing out.  If and when there's a fix to ld.lld, this can
be converted to a version check instead so that users of older but still
supported versions of ld.lld don't hurt themselves by enabling
CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y.

Link: ClangBuiltLinux#1881
Link: https://lore.kernel.org/linux-riscv/ZJXTwqZIkXLxXaSi@google.com/
Reported-by: Palmer Dabbelt <palmer@dabbelt.com>
Suggested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
@nickdesaulniers
Copy link
Member Author

nickdesaulniers commented Sep 19, 2023

(This might be related to lld not discarding locals by default as bfd does; -Wl,-X)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[ARCH] risc-v This bug impacts ARCH=riscv [TOOL] lld The issue is relevant to LLD linker
Projects
None yet
Development

No branches or pull requests

2 participants