Re: [PATCH 18/23] objtool: cache relocations and function dead end state, do less work
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
Date: 2026-09-13 20:28:58
Also in:
linux-arch, linux-doc, linux-efi, linux-kbuild, linux-riscv, lkml, llvm
On Sat, Sep 12, 2026 at 03:47:33PM -0700, Josh Poimboeuf wrote:
On Tue, Sep 08, 2026 at 09:55:18PM +0100, Lorenzo Stoakes (ARM) wrote:quoted
Whole build, 128-thread Threadripper 9980X, best of N runs: before after delta ------------------------------- x86 defconfig, touch mm/vma.c, gcc 8.4s 8.1s -0.28s (-3%) x86 defconfig, touch mm/vma.c, clang 7.5s 7.1s -0.41s (-5%) x86 defconfig, clean, gcc 27.1s 26.8s -0.34s (-1%) x86 defconfig, clean, clang 26.6s 26.2s -0.40s (-1%) x86 allmodconfig, touch mm/vma.c, gcc 30.2s 28.4s -1.8s (-6%) x86 allmodconfig, touch mm/vma.c, clang 28.1s 26.0s -2.1s (-7%)Nice!quoted
@@ -305,7 +305,15 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, static bool dead_end_function(struct objtool_file *file, struct symbol *func) { - return __dead_end_function(file, func, 0); + if (!func) + return false; + + if (!func->dead_end_known) { + func->dead_end = __dead_end_function(file, func, 0); + func->dead_end_known = 1; + } + + return func->dead_end; }This bit seems like it should be a separate patch. Though actually, it can just be dropped as I have something similar brewing: https://lore.kernel.org/9d4b8ccfed745ac47a954aa2e1de62a85197122d.1788899473.git.jpoimboe@kernel.org (local)
Ack, dropped for v2, will reference that seris in the cover.
quoted
-struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset) +/* Should never be invoked, provided as a backstop. */ +static struct reloc *find_reloc_linear(struct section *rsec, + unsigned long offset, unsigned int len) { - return find_reloc_by_dest_range(elf, sec, offset, 1); + struct reloc *reloc, *first = NULL; + + WARN("%s: linear scan for sec %s with %u relocs at offset %lu len %u", + __func__, rsec->name, sec_num_entries(rsec), offset, len);Won't this be triggered for sections created with elf_create_rela_section()? I don't see where they set rsec->hashed.
Good catch thanks, it was triggering for those, e.g. CONFIG_LIVEPATCH, repro'd locally. Updated the code to hash these too correctly for v3.
quoted
@@ -1147,6 +1307,28 @@ static int read_relocs(struct elf *elf) rsec->base->rsec = rsec; + /* DWARF relocs are never looked up. */ + if (is_dwarf_section(rsec->base)) + continue; + if (reloc_sec_in_order(rsec)) { + rsec->sorted = true; + continue; + } + + rsec->hashed = true; + nr_hashed += sec_num_entries(rsec); + }Hm, I'm not sure whether hashing is even still needed, as compilers generally emit sorted relocs.
They do, and anything read from the file in the build does, but this is a fallback for sections that objtool grows or creates itself which needs the duplicate check + can be appended out of order.
quoted
@@ -1592,6 +1799,7 @@ static int elf_alloc_reloc(struct elf *elf, struct section *rsec) } rsec->nr_alloc_relocs = nr_alloc; + copy_reloc_cache_to_hash(elf, rsec, nr_relocs_old);Not all relocation appends go through this allocation code path. It can return earlier in this function if the space has already been allocated previously. So this call probably belongs in elf_create_reloc().
Ack thanks, fixed for v2.
-- Josh
-- Cheers, Lorenzo