diff options
author | Peter Zijlstra <peterz@infradead.org> | 2020-03-12 11:23:36 +0100 |
---|---|---|
committer | Peter Zijlstra <peterz@infradead.org> | 2020-03-25 18:28:30 +0100 |
commit | 8b5fa6bc326bf02f293b5a39a8f5b3de816265d3 (patch) | |
tree | 11121ed0c5015841e16a84207a1bf80a31f09dfb /tools/objtool/orc_gen.c | |
parent | cdb3d057a17d56363a831e486ea39e4c389a6cf9 (diff) | |
download | lwn-8b5fa6bc326bf02f293b5a39a8f5b3de816265d3.tar.gz lwn-8b5fa6bc326bf02f293b5a39a8f5b3de816265d3.zip |
objtool: Optimize read_sections()
Perf showed that __hash_init() is a significant portion of
read_sections(), so instead of doing a per section rela_hash, use an
elf-wide rela_hash.
Statistics show us there are about 1.1 million relas, so size it
accordingly.
This reduces the objtool on vmlinux.o runtime to a third, from 15 to 5
seconds.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lkml.kernel.org/r/20200324160924.739153726@infradead.org
Diffstat (limited to 'tools/objtool/orc_gen.c')
-rw-r--r-- | tools/objtool/orc_gen.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index 27a4112848c2..41e4a2754da4 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -81,7 +81,7 @@ int create_orc(struct objtool_file *file) return 0; } -static int create_orc_entry(struct section *u_sec, struct section *ip_relasec, +static int create_orc_entry(struct elf *elf, struct section *u_sec, struct section *ip_relasec, unsigned int idx, struct section *insn_sec, unsigned long insn_off, struct orc_entry *o) { @@ -109,9 +109,10 @@ static int create_orc_entry(struct section *u_sec, struct section *ip_relasec, rela->addend = insn_off; rela->type = R_X86_64_PC32; rela->offset = idx * sizeof(int); + rela->sec = ip_relasec; list_add_tail(&rela->list, &ip_relasec->rela_list); - hash_add(ip_relasec->rela_hash, &rela->hash, rela->offset); + hash_add(elf->rela_hash, &rela->hash, rela_hash(rela)); return 0; } @@ -182,7 +183,7 @@ int create_orc_sections(struct objtool_file *file) if (!prev_insn || memcmp(&insn->orc, &prev_insn->orc, sizeof(struct orc_entry))) { - if (create_orc_entry(u_sec, ip_relasec, idx, + if (create_orc_entry(file->elf, u_sec, ip_relasec, idx, insn->sec, insn->offset, &insn->orc)) return -1; @@ -194,7 +195,7 @@ int create_orc_sections(struct objtool_file *file) /* section terminator */ if (prev_insn) { - if (create_orc_entry(u_sec, ip_relasec, idx, + if (create_orc_entry(file->elf, u_sec, ip_relasec, idx, prev_insn->sec, prev_insn->offset + prev_insn->len, &empty)) |