Thread (105 messages) flat view 105 messages, 14 authors, 10d ago

Re: [PATCH 18/23] objtool: cache relocations and function dead end state, do less work

From: Josh Poimboeuf <jpoimboe@kernel.org>
Date: 2026-09-12 22:47:37
Also in: linux-arch, linux-efi, linux-kbuild, linux-riscv, lkml, llvm, rust-for-linux

On Tue, Sep 08, 2026 at 09:55:18PM +0100, Lorenzo Stoakes (ARM) wrote:
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 hunk ↗ jump to hunk
@@ -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)
-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.
quoted hunk ↗ jump to hunk
@@ -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.
quoted hunk ↗ jump to hunk
@@ -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().

-- 
Josh
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help