From patchwork Thu Nov 28 01:24:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13887518 Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B7621EEE0 for ; Thu, 28 Nov 2024 01:24:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732757059; cv=none; b=L4z3c8yzf+6YwKM+jk3fdPr2V84INpbyz6KS59SSG7XSb0QMxH7qsBYqDisq8ZBdG5Fy08qcbPo/XMvcvTTUTRKTF3m8pVQufvFJb/vqbGfKyNW9NsJSc4s4uuvuxo99ysdM5vcotwDaPwavmLC2V4NXDRFGr/jpTgVyw/JkQlc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732757059; c=relaxed/simple; bh=AcekpYPUz6WXe/HocDja5CWE/JskoSENnlv96FjlCI8=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=I4pdIeaODKtzv+emmIfra33gxseJ8BK/u45nj6lwrFGrUoysIz+mGpDrCwXxQGhLUhtzlhdVOiP7zkmiWB9s+G8RiusP43TRA2FsgnQoc8c/OLXIhpgm4jjbsyXfWMG6PAaxwTgw14HUxYThhYyzDMdjQqeSp2Qp1zWWi6aWUPA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=pDxsZ6Hh; arc=none smtp.client-ip=185.70.43.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="pDxsZ6Hh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1732757055; x=1733016255; bh=jaw2NQ06s5/YdtWm4Ky06nvWSpFOKNi8xjlLNi0SoWQ=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=pDxsZ6HhShjjyrvnDDrVdPbAVQwzyc4viDDIXIRNjvArcSVbAXOUI4gB5qjitPB5S K/Cp/zA5GRLdhpSnadtAx2U+wp1CSC0k7uwNpsldMJV7EZRet6N2bS8wTELbhYLK8l jYlteXtFGyFbRalOW38SIxjl/cLeB5aJoYPGl3557hgOzbi332AFBORdinPk0prOrA gbdVNcpyrwEo0SwN8ULp8YLp4qUbnW3cNNBneeT2sc96gmyWP/OOZ5JpFLLKvdP21p c9HZLv1Wx6De3asb42lHHvs8EI+EAQl5mB3F0WslMWqTdi++3qIKOPnCdnv9IyKmeL 9z12sRISRUxmw== Date: Thu, 28 Nov 2024 01:24:13 +0000 To: dwarves@vger.kernel.org, acme@kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com Subject: [RFC PATCH 7/9] btf_encoder: switch to shared elf_functions table Message-ID: <20241128012341.4081072-8-ihor.solodrai@pm.me> In-Reply-To: <20241128012341.4081072-1-ihor.solodrai@pm.me> References: <20241128012341.4081072-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: 5fa30f01a4e43a861beb08b6870c293b5e23b016 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-State: RFC Do not collect functions from ELF for each new btf_encoder, and instead set a pointer to a shared elf_functions table, built beforehand by btf_encoder__pre_cus__load_module(). Do not call btf_encoder__add_saved_funcs() on every btf_encoder__add_encoder(). Instead, for non-reproducible multi-threaded case do that in pahole_threads_collect(), and for single-threaded or reproducible_build do that right before btf_encoder__encode(). Signed-off-by: Ihor Solodrai Acked-by: Eduard Zingerman --- btf_encoder.c | 42 +++++++++++++++++++----------------------- btf_encoder.h | 1 + pahole.c | 9 ++++++++- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index 8b1db5b..778481d 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -137,7 +137,7 @@ struct btf_encoder { size_t seccnt; int encode_vars; struct list_head func_states; - struct elf_functions functions; + struct elf_functions *functions; }; struct btf_func { @@ -159,6 +159,19 @@ struct btf_kfunc_set_range { */ static LIST_HEAD(elf_functions_list); +static struct elf_functions *elf_functions__get(Elf *elf) +{ + struct list_head *pos; + + list_for_each(pos, &elf_functions_list) { + struct elf_functions *funcs = list_entry(pos, struct elf_functions, node); + + if (funcs->elf == elf) + return funcs; + } + return NULL; +} + static inline void elf_functions__delete(struct elf_functions *funcs) { free(funcs->entries); @@ -215,8 +228,6 @@ out_delete: static LIST_HEAD(encoders); static pthread_mutex_t encoders__lock = PTHREAD_MUTEX_INITIALIZER; -static int btf_encoder__add_saved_funcs(struct btf_encoder *encoder); - /* mutex only needed for add/delete, as this can happen in multiple encoding * threads. Traversal of the list is currently confined to thread collection. */ @@ -869,8 +880,6 @@ int32_t btf_encoder__add_encoder(struct btf_encoder *encoder, struct btf_encoder if (encoder == other) return 0; - btf_encoder__add_saved_funcs(other); - for (shndx = 1; shndx < other->seccnt; shndx++) { struct gobuffer *var_secinfo_buf = &other->secinfo[shndx].secinfo; size_t sz = gobuffer__size(var_secinfo_buf); @@ -1333,7 +1342,7 @@ static void btf_encoder__delete_saved_funcs(struct btf_encoder *encoder) } } -static int btf_encoder__add_saved_funcs(struct btf_encoder *encoder) +int btf_encoder__add_saved_funcs(struct btf_encoder *encoder) { struct btf_encoder_func_state **saved_fns, *s; struct btf_encoder *e = NULL; @@ -1430,7 +1439,7 @@ static struct elf_function *btf_encoder__find_function(const struct btf_encoder { struct elf_function key = { .name = name, .prefixlen = prefixlen, .addr = addr }; - return bsearch(&key, encoder->functions.entries, encoder->functions.cnt, sizeof(key), functions_cmp); + return bsearch(&key, encoder->functions->entries, encoder->functions->cnt, sizeof(key), functions_cmp); } static bool btf_name_char_ok(char c, bool first) @@ -2118,9 +2127,6 @@ int btf_encoder__encode(struct btf_encoder *encoder) int err; size_t shndx; - /* for single-threaded case, saved funcs are added here */ - btf_encoder__add_saved_funcs(encoder); - for (shndx = 1; shndx < encoder->seccnt; shndx++) if (gobuffer__size(&encoder->secinfo[shndx].secinfo)) btf_encoder__add_datasec(encoder, shndx); @@ -2488,8 +2494,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam printf("%s: '%s' doesn't have symtab.\n", __func__, cu->filename); goto out; } - encoder->functions.symtab = encoder->symtab; - encoder->functions.elf = cu->elf; + encoder->functions = elf_functions__get(cu->elf); /* index the ELF sections for later lookup */ @@ -2528,9 +2533,6 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam if (!found_percpu && encoder->verbose) printf("%s: '%s' doesn't have '%s' section\n", __func__, cu->filename, PERCPU_SECTION); - if (elf_functions__collect(&encoder->functions)) - goto out_delete; - if (encoder->verbose) printf("File %s:\n", cu->filename); btf_encoders__add(encoder); @@ -2559,12 +2561,6 @@ void btf_encoder__delete(struct btf_encoder *encoder) encoder->btf = NULL; elf_symtab__delete(encoder->symtab); - encoder->functions.cnt = 0; - free(encoder->functions.entries); - encoder->functions.entries = NULL; - - btf_encoder__delete_saved_funcs(encoder); - free(encoder); } @@ -2661,7 +2657,7 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co continue; if (!ftype__has_arg_names(&fn->proto)) continue; - if (encoder->functions.cnt) { + if (encoder->functions->cnt) { const char *name; uint64_t addr; @@ -2673,7 +2669,7 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co /* prefer exact function name match... */ func = btf_encoder__find_function(encoder, name, 0, addr); - if (!func && encoder->functions.suffix_cnt && + if (!func && encoder->functions->suffix_cnt && conf_load->btf_gen_optimized) { /* falling back to name.isra.0 match if no exact * match is found; only bother if we found any diff --git a/btf_encoder.h b/btf_encoder.h index 7debd67..29f652a 100644 --- a/btf_encoder.h +++ b/btf_encoder.h @@ -33,6 +33,7 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co struct btf *btf_encoder__btf(struct btf_encoder *encoder); int btf_encoder__add_encoder(struct btf_encoder *encoder, struct btf_encoder *other); +int btf_encoder__add_saved_funcs(struct btf_encoder *base_encoder); int btf_encoder__pre_load_module(Dwfl_Module *mod, Elf *elf); diff --git a/pahole.c b/pahole.c index 1f8cf4b..b5aea56 100644 --- a/pahole.c +++ b/pahole.c @@ -3185,12 +3185,16 @@ static int pahole_threads_collect(struct conf_load *conf, int nr_threads, void * if (error) goto out; + err = btf_encoder__add_saved_funcs(btf_encoder); + if (err < 0) + goto out; + for (i = 0; i < nr_threads; i++) { /* * Merge content of the btf instances of worker threads to the btf * instance of the primary btf_encoder. */ - if (!threads[i]->btf) + if (!threads[i]->encoder || !threads[i]->btf) continue; err = btf_encoder__add_encoder(btf_encoder, threads[i]->encoder); if (err < 0) @@ -3845,6 +3849,9 @@ try_sole_arg_as_class_names: exit(1); } + if (conf_load.nr_jobs <= 1 || conf_load.reproducible_build) + btf_encoder__add_saved_funcs(btf_encoder); + err = btf_encoder__encode(btf_encoder); if (err) { fputs("Failed to encode BTF\n", stderr);