]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
objtool/klp: Cache dont_correlate() result
authorJosh Poimboeuf <jpoimboe@kernel.org>
Mon, 20 Apr 2026 04:06:28 +0000 (21:06 -0700)
committerJosh Poimboeuf <jpoimboe@kernel.org>
Tue, 5 May 2026 04:16:07 +0000 (21:16 -0700)
Cache the dont_correlate() result once per symbol at the start of
correlate_symbols().  This reduces klp diff time on an arm64 LTO
vmlinux.o from 2m51s to 35s.

Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
tools/objtool/include/objtool/elf.h
tools/objtool/klp-diff.c

index fccf72cbd343bfac7e6c354d4022340eb3eb4f32..d9c44df9cc76a4e916352be9948e9115cc25fbe9 100644 (file)
@@ -96,6 +96,7 @@ struct symbol {
        u8 changed           : 1;
        u8 included          : 1;
        u8 klp               : 1;
+       u8 dont_correlate    : 1;
        struct list_head pv_target;
        struct reloc *relocs;
        struct section *group_sec;
index ed3bf1c55001a18fc69515752d8ddd4fec2185cb..f8787d7d14547f8c0607f362e3b298a730888263 100644 (file)
@@ -524,7 +524,7 @@ static struct symbol *find_twin(struct elfs *e, struct symbol *sym1)
 
        /* Count orig candidates */
        for_each_sym_by_demangled_name(e->orig, sym1->demangled_name, sym2) {
-               if (sym2->twin || sym1->type != sym2->type || dont_correlate(sym2) ||
+               if (sym2->twin || sym1->type != sym2->type || sym2->dont_correlate ||
                    (!maybe_same_file(sym1, sym2)))
                        continue;
 
@@ -550,7 +550,7 @@ static struct symbol *find_twin(struct elfs *e, struct symbol *sym1)
 
        /* Count patched candidates */
        for_each_sym_by_demangled_name(e->patched, sym1->demangled_name, sym2) {
-               if (sym2->twin || sym1->type != sym2->type || dont_correlate(sym2) ||
+               if (sym2->twin || sym1->type != sym2->type || sym2->dont_correlate ||
                    !maybe_same_file(sym1, sym2))
                        continue;
 
@@ -693,7 +693,7 @@ static struct symbol *find_twin_suffixed(struct elf *elf, struct symbol *sym1)
                return NULL;
 
        for_each_sym_by_name(elf, name, sym2) {
-               if (sym2->twin || sym1->type != sym2->type || dont_correlate(sym2))
+               if (sym2->twin || sym1->type != sym2->type || sym2->dont_correlate)
                        continue;
                count++;
                match = sym2;
@@ -733,7 +733,7 @@ static struct symbol *find_twin_positional(struct elfs *e, struct symbol *sym1)
        struct symbol *sym2, *match = NULL;
 
        for_each_sym_by_demangled_name(e->orig, sym1->demangled_name, sym2) {
-               if (sym2->twin || sym1->type != sym2->type || dont_correlate(sym2) ||
+               if (sym2->twin || sym1->type != sym2->type || sym2->dont_correlate ||
                    !maybe_same_file(sym1, sym2))
                        continue;
                if (is_tu_local_sym(sym1) != is_tu_local_sym(sym2) ||
@@ -745,7 +745,7 @@ static struct symbol *find_twin_positional(struct elfs *e, struct symbol *sym1)
        }
 
        for_each_sym_by_demangled_name(e->patched, sym1->demangled_name, sym2) {
-               if (sym2->twin || sym1->type != sym2->type || dont_correlate(sym2) ||
+               if (sym2->twin || sym1->type != sym2->type || sym2->dont_correlate ||
                    !maybe_same_file(sym1, sym2))
                        continue;
                if (is_tu_local_sym(sym1) != is_tu_local_sym(sym2) ||
@@ -777,6 +777,11 @@ static int correlate_symbols(struct elfs *e)
        struct symbol *sym1, *sym2;
        bool progress;
 
+       for_each_sym(e->orig, sym1)
+               sym1->dont_correlate = dont_correlate(sym1);
+       for_each_sym(e->patched, sym2)
+               sym2->dont_correlate = dont_correlate(sym2);
+
        /* Correlate FILE symbols */
        file1_sym = first_file_symbol(e->orig);
        file2_sym = first_file_symbol(e->patched);
@@ -817,7 +822,7 @@ static int correlate_symbols(struct elfs *e)
        do {
                progress = false;
                for_each_sym(e->orig, sym1) {
-                       if (sym1->twin || dont_correlate(sym1))
+                       if (sym1->twin || sym1->dont_correlate)
                                continue;
                        sym2 = find_twin(e, sym1);
                        if (!sym2)
@@ -831,7 +836,7 @@ static int correlate_symbols(struct elfs *e)
                        return -1;
 
                for_each_sym(e->orig, sym1) {
-                       if (sym1->twin || dont_correlate(sym1))
+                       if (sym1->twin || sym1->dont_correlate)
                                continue;
                        sym2 = find_twin_suffixed(e->patched, sym1);
                        if (!sym2)
@@ -843,7 +848,7 @@ static int correlate_symbols(struct elfs *e)
        } while (progress);
 
        for_each_sym(e->orig, sym1) {
-               if (sym1->twin || dont_correlate(sym1))
+               if (sym1->twin || sym1->dont_correlate)
                        continue;
                sym2 = find_twin_positional(e, sym1);
                if (!sym2)
@@ -853,7 +858,7 @@ static int correlate_symbols(struct elfs *e)
        }
 
        for_each_sym(e->orig, sym1) {
-               if (sym1->twin || dont_correlate(sym1))
+               if (sym1->twin || sym1->dont_correlate)
                        continue;
                WARN("no correlation: %s", sym1->name);
        }
@@ -1066,7 +1071,7 @@ static int mark_changed_functions(struct elfs *e)
 
        /* Find changed functions */
        for_each_sym(e->orig, orig_sym) {
-               if (dont_correlate(orig_sym))
+               if (orig_sym->dont_correlate)
                        continue;
 
                patched_sym = orig_sym->twin;
@@ -1087,7 +1092,7 @@ static int mark_changed_functions(struct elfs *e)
 
        /* Find added functions and print them */
        for_each_sym(e->patched, patched_sym) {
-               if (!is_func_sym(patched_sym) || dont_correlate(patched_sym))
+               if (!is_func_sym(patched_sym) || patched_sym->dont_correlate)
                        continue;
 
                if (!patched_sym->twin) {
@@ -1193,7 +1198,7 @@ static bool klp_reloc_needed(struct reloc *patched_reloc)
        struct export *export;
 
        /* no external symbol to reference */
-       if (dont_correlate(patched_sym))
+       if (patched_sym->dont_correlate)
                return false;
 
        /* For included functions, a regular reloc will do. */