[PATCH 2/3] objtool: optimize insn_hash for split sections

From: Sami Tolvanen
Date: Tue Apr 21 2020 - 14:07:40 EST


When running objtool on vmlinux.o compiled with -ffunction-sections,
we end up with a ton of collisions in the insn_hash table as each
function is in its own section. This results in a runtime of minutes
instead of seconds. Use both section index and offset as the key to
avoid this, similarly to rela_hash.

Signed-off-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx>
---
tools/objtool/check.c | 5 +++--
tools/objtool/check.h | 5 +++++
2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 4b170fd08a28..4770fb07b365 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -34,7 +34,8 @@ struct instruction *find_insn(struct objtool_file *file,
{
struct instruction *insn;

- hash_for_each_possible(file->insn_hash, insn, hash, offset)
+ hash_for_each_possible(file->insn_hash, insn, hash,
+ sec_offset_hash(sec, offset))
if (insn->sec == sec && insn->offset == offset)
return insn;

@@ -273,7 +274,7 @@ static int decode_instructions(struct objtool_file *file)
if (ret)
goto err;

- hash_add(file->insn_hash, &insn->hash, insn->offset);
+ hash_add(file->insn_hash, &insn->hash, insn_hash(insn));
list_add_tail(&insn->list, &file->insn_list);
nr_insns++;
}
diff --git a/tools/objtool/check.h b/tools/objtool/check.h
index f0ce8ffe7135..bc78eca7982e 100644
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -56,6 +56,11 @@ struct objtool_file {

int check(const char *objname, bool orc);

+static inline u32 insn_hash(struct instruction *insn)
+{
+ return sec_offset_hash(insn->sec, insn->offset);
+}
+
struct instruction *find_insn(struct objtool_file *file,
struct section *sec, unsigned long offset);

--
2.26.1.301.g55bc3eb7cb9-goog