From patchwork Tue Jan 7 19:09:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13929525 Received: from mail-10630.protonmail.ch (mail-10630.protonmail.ch [79.135.106.30]) (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 B10E718FDD2; Tue, 7 Jan 2025 19:09:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276952; cv=none; b=RJ9xwEuQVxtHlqxaiJWSf+X+iFjpIgPZGitdPLD0B5n2cTUkUUcQ+WPFgUj/5Cp17Phihrx4SlQH9s1mWvEd+38OaRy+6JtP4B1GEylVrplHnDV/lRjxyBr79q6NhbJDKUJDi2yXf8P784C0O/AVNEFlDruCoqkgB2ktfqoY8Mw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276952; c=relaxed/simple; bh=dySSB0RGJEkU2f2fyoTgxCQRAftkucTKcJk4MztaF4o=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Ll5wSE8yR6M8wJIoMDU7pwtm+MKGqAUN0kFXp8ecJFHPz9PCyzh9l9kW9e1ziFNlHkkss3jU6BZnfK3jS3z9RXoC+b+tMi2DxEqyXEND7gifGG8rXIVpZD+xzHd2jvJpFX4XLkgJjtkEWfyqt7eJzh/v9SlxNcPW47sr8Y/d7nU= 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=OybTIgW1; arc=none smtp.client-ip=79.135.106.30 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="OybTIgW1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736276947; x=1736536147; bh=2Q4VXTMtpMVCKGOkGDpzz8LKAjMiPCKFGdDDgMYRKKI=; 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=OybTIgW1MSGaHUHl9xhrDQAX0RSFP8MB6PBAK0QoyFg+s0rqY6WNrbKWJH/ZZ9SRK FemD5/+x3/sqOE9NDI5Z2oTojinpL1pQ4s/S8p+pjstdZDc26PJmwjgobIZ7B3qDkX NUjP055MInvx8oOQxKA6VBakHWogLJXyNtJ47AhcwrPY+FfFVUawZlso1ADF2XiX0S o9iiRAHvm44EYkNM9FHBI7ffOhE7pzWUVGA9f9xPeOwY9NeDO/LD5/olwRpIrQiUHh nMVb+Qg3KcYcHWnpEgyDgNH+OMH8chpPwpMOesq9nGzwoZRAvcv4X9RCjG7GNCdUIO L1d9VE//PYWoQ== Date: Tue, 07 Jan 2025 19:09:03 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 01/10] btf_encoder: simplify function encoding Message-ID: <20250107190855.2312210-2-ihor.solodrai@pm.me> In-Reply-To: <20250107190855.2312210-1-ihor.solodrai@pm.me> References: <20250107190855.2312210-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: 01a2101a254da4c1b43707bf361aeb26425b7d9c Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alan Maguire Currently we have two modes of function encoding; one adds functions based upon the first instance found and ignores inconsistent representations. The second saves function representations and later finds inconsistencies. The mode chosen is determined by conf_load->skip_encoding_btf_inconsistent_proto. The knock-on effect is that we need to support two modes in btf_encoder__add_func(); one for each case. Simplify by using the "save function" approach for both cases; only difference is that we allow inconsistent representations if skip_encoding_btf_inconsistent_proto is not set (it is set by default for upstream kernels and has been for a while). Signed-off-by: Alan Maguire Signed-off-by: Ihor Solodrai Acked-by: Eduard Zingerman Acked-by: Jiri Olsa Link: https://lore.kernel.org/dwarves/20241128012341.4081072-2-ihor.solodrai@pm.me/ --- btf_encoder.c | 79 +++++++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 53 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index fbc9509..2e51afd 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -88,7 +88,6 @@ struct btf_encoder_func_state { struct elf_function { const char *name; char *alias; - bool generated; size_t prefixlen; struct btf_encoder_func_state state; }; @@ -120,6 +119,7 @@ struct btf_encoder { force, gen_floats, skip_encoding_decl_tag, + skip_encoding_inconsistent_proto, tag_kfuncs, gen_distilled_base; uint32_t array_index_id; @@ -1165,18 +1165,18 @@ out: return err; } -static int32_t btf_encoder__add_func(struct btf_encoder *encoder, struct function *fn, +static int32_t btf_encoder__add_func(struct btf_encoder *encoder, struct elf_function *func) { + struct btf_encoder_func_state *state = &func->state; int btf_fnproto_id, btf_fn_id, tag_type_id = 0; int16_t component_idx = -1; const char *name; const char *value; char tmp_value[KSYM_NAME_LEN]; + uint16_t idx; - assert(fn != NULL || func != NULL); - - btf_fnproto_id = btf_encoder__add_func_proto(encoder, fn ? &fn->proto : NULL, func); + btf_fnproto_id = btf_encoder__add_func_proto(encoder, NULL, func); name = func->alias ?: func->name; if (btf_fnproto_id >= 0) btf_fn_id = btf_encoder__add_ref_type(encoder, BTF_KIND_FUNC, btf_fnproto_id, @@ -1186,40 +1186,23 @@ static int32_t btf_encoder__add_func(struct btf_encoder *encoder, struct functio name, btf_fnproto_id < 0 ? "proto" : "func"); return -1; } - if (!fn) { - struct btf_encoder_func_state *state = &func->state; - uint16_t idx; - - if (state->nr_annots == 0) - return 0; + if (state->nr_annots == 0) + return 0; - for (idx = 0; idx < state->nr_annots; idx++) { - struct btf_encoder_func_annot *a = &state->annots[idx]; + for (idx = 0; idx < state->nr_annots; idx++) { + struct btf_encoder_func_annot *a = &state->annots[idx]; - value = btf__str_by_offset(encoder->btf, a->value); - /* adding BTF data may result in a mode of the - * value string memory, so make a temporary copy. - */ - strncpy(tmp_value, value, sizeof(tmp_value) - 1); - component_idx = a->component_idx; - - tag_type_id = btf_encoder__add_decl_tag(encoder, tmp_value, - btf_fn_id, component_idx); - if (tag_type_id < 0) - break; - } - } else { - struct llvm_annotation *annot; - - list_for_each_entry(annot, &fn->annots, node) { - value = annot->value; - component_idx = annot->component_idx; + value = btf__str_by_offset(encoder->btf, a->value); + /* adding BTF data may result in a mode of the + * value string memory, so make a temporary copy. + */ + strncpy(tmp_value, value, sizeof(tmp_value) - 1); + component_idx = a->component_idx; - tag_type_id = btf_encoder__add_decl_tag(encoder, value, btf_fn_id, - component_idx); - if (tag_type_id < 0) - break; - } + tag_type_id = btf_encoder__add_decl_tag(encoder, tmp_value, + btf_fn_id, component_idx); + if (tag_type_id < 0) + break; } if (tag_type_id < 0) { fprintf(stderr, @@ -1277,8 +1260,9 @@ static int btf_encoder__add_saved_funcs(struct btf_encoder *encoder) * just do not _use_ them. Only exclude functions with * unexpected register use or multiple inconsistent prototypes. */ - if (!state->unexpected_reg && !state->inconsistent_proto) { - if (btf_encoder__add_func(encoder, NULL, func)) + if (!encoder->skip_encoding_inconsistent_proto || + (!state->unexpected_reg && !state->inconsistent_proto)) { + if (btf_encoder__add_func(encoder, func)) return -1; } state->processed = 1; @@ -2359,6 +2343,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam encoder->force = conf_load->btf_encode_force; encoder->gen_floats = conf_load->btf_gen_floats; encoder->skip_encoding_decl_tag = conf_load->skip_encoding_btf_decl_tag; + encoder->skip_encoding_inconsistent_proto = conf_load->skip_encoding_btf_inconsistent_proto; encoder->tag_kfuncs = conf_load->btf_decl_tag_kfuncs; encoder->gen_distilled_base = conf_load->btf_gen_distilled_base; encoder->verbose = verbose; @@ -2564,7 +2549,6 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co cu__for_each_function(cu, core_id, fn) { struct elf_function *func = NULL; - bool save = false; /* * Skip functions that: @@ -2586,15 +2570,8 @@ 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); - if (func) { - if (func->generated) - continue; - if (conf_load->skip_encoding_btf_inconsistent_proto) - save = true; - else - func->generated = true; - } else if (encoder->functions.suffix_cnt && - conf_load->btf_gen_optimized) { + 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 * .suffix function names. The function @@ -2605,7 +2582,6 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co func = btf_encoder__find_function(encoder, name, strlen(name)); if (func) { - save = true; if (encoder->verbose) printf("matched function '%s' with '%s'%s\n", name, func->name, @@ -2624,10 +2600,7 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co if (!func) continue; - if (save) - err = btf_encoder__save_func(encoder, fn, func); - else - err = btf_encoder__add_func(encoder, fn, func); + err = btf_encoder__save_func(encoder, fn, func); if (err) goto out; } From patchwork Tue Jan 7 19:09:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13929527 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 185531F4E29; Tue, 7 Jan 2025 19:09:22 +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=1736276966; cv=none; b=Inx7uQU9VXQ0P/BoSQpA4ali5URGYMHX7tvmZ3zJgQLVyZ1jRfKOro4I1sITCPgMzziX2HJWf9koEfp5IWkVwpA6mbMYQz1RawW5ZlWuB8oyVqgjZ/jpHVbBUTTJbk2FAtt3q2iqErgugSdYoQdymwM0GsyHph9T53NdY1yKsxU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276966; c=relaxed/simple; bh=LSXxYJXI1/a5lYvOsKGKTi34t3dhW6RnI45SOWi99cY=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=eqE/JkxQhH2TiD924NGFgwWJLGpfFR0GUZOYjAtv1c24IcGx5/i1+Zt50CyoIna0c0QRTaZsSw4/ZgtyvekrbDxInR1PqPwo0ZnGXdtp2R8iJJD54TsTaYKWtPatLFngwIU40hmDSgi4Gz6IA9dJosdn7Ey8DCHygJob3qbyUSQ= 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=PCB2LT2W; 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="PCB2LT2W" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736276954; x=1736536154; bh=LSXxYJXI1/a5lYvOsKGKTi34t3dhW6RnI45SOWi99cY=; 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=PCB2LT2WBZJqq0uJ7yABUZdbsW27WlQTM9k0F2Cq0rgPQgFrBYgpsBkWBwZORPvoi DoscldOChLMe4k8BPW+j0I7k/xreOg76Jn/2GQvMzqtgQzUCdv0RdE1qiXHeAVVcKl MyKd7xFox4yaD24YSQCj4uPmiBxdPoIZf5pG/bZoPAF7NRzUGh2nWhZ6z1wCCZl8tu RBUUjqCeumlmCy9L2foKs4hZvgL8ZeDWVlYLqWYVa1vGwvE7pnp0+Si3LHJSQkzsdJ tTiJ0JR0XJDvhGH9DaRUrWoZEYYzwmahXJa1jDkFzdIJldMIG8xsIMaLB6Akg//waG 9q/vHqJOPbjIw== Date: Tue, 07 Jan 2025 19:09:10 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 02/10] btf_encoder: free encoder->secinfo in btf_encoder__delete Message-ID: <20250107190855.2312210-3-ihor.solodrai@pm.me> In-Reply-To: <20250107190855.2312210-1-ihor.solodrai@pm.me> References: <20250107190855.2312210-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: cbbe895be26f12b3128991d6b620b2fe614d5f46 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 encoder->secinfo is allocated in btf_encoder__new and is never freed. Fix that. Link: https://lore.kernel.org/dwarves/YiiVvWJxHUyK75b4FqlvAOnHvX9WLzCsRLG-236zf_cPZy1jmgbUq2xM4ChxRob1kaTVUdtVljtcpL2Cs3v1wXPGcP8dPeASBiYVGH3jEaQ=@pm.me/ Signed-off-by: Ihor Solodrai Reviewed-by: Alan Maguire --- btf_encoder.c | 1 + 1 file changed, 1 insertion(+) diff --git a/btf_encoder.c b/btf_encoder.c index 2e51afd..6720065 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -2453,6 +2453,7 @@ void btf_encoder__delete(struct btf_encoder *encoder) btf_encoders__delete(encoder); for (shndx = 0; shndx < encoder->seccnt; shndx++) __gobuffer__delete(&encoder->secinfo[shndx].secinfo); + free(encoder->secinfo); zfree(&encoder->filename); zfree(&encoder->source_filename); btf__free(encoder->btf); From patchwork Tue Jan 7 19:09:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13929529 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 44CA91F37BE for ; Tue, 7 Jan 2025 19:09:28 +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=1736276972; cv=none; b=rgnovMpp1zK38+U7nOV5UIwRbWdIW2TulkUlMBFdFlFPjS2+clhrL/nXQVONffY4U/HOEMHowZ076Et6WwveuIEfJNMNXZ+ag8TYbTck01bUXt0G3pIvBxBgISY5q6I4neibIgGRsdlth+KhXQSVsHoIDEJQDQQMXJMVVH8y20A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276972; c=relaxed/simple; bh=PPDb17RnDA3VmZe8Oe8PHHuu5L/3+L+9+5SisuEgavE=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Quv8UuF1khQnIHscm7Nay2e/qplJBXC6i2TrJccuyew/n5yVh6ENQXS0fBxkQ3OZWYCGW2CJCaI0T/dT0lEUMR9kBNLz9kgUK5RZ3DwtLafgQljAR1fmyvkS0lXt32cuKLGumT0GCzDfUMXaSK+aVn/wlflJuTW/Q4vox9FwFLc= 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=DIPK9UQ2; 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="DIPK9UQ2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736276959; x=1736536159; bh=20Cf+a9VscFlxGoH0cRRtFmsePrk0cGPF4d6eSMZ+Kg=; 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=DIPK9UQ2TcqKLNKe4xxOzpbOuogrVYPfkgfrWWVUXMDfV/0JYLhW5qwfT3pYckifd cKRZMrdFGuNxlKjayBd6BwBvKHKsG4QI98oGNPLqHPbYDJS8i6lbjjDfLQ0FhdlygW gTwmw0Yu9MHNB6YPabFMPNhAsDWh6ReaB3h4aTAZKl4QBQp0CpBJpXheNRq3o7qjIH V+yRwCBTz8CryxwGbiXnlnKdWsKyt6q77zYY9ZM5gNSYS/soD8ohHNwj98aDi4R6Wa FcFG72qveLYvmtkLGFHOfY0DDgdwzQrK3oMGwfGQ4w4cYkomzVsp93G8yq+8/WeEPs obQaNvoKEWy8g== Date: Tue, 07 Jan 2025 19:09:16 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 03/10] btf_encoder: separate elf function, saved function representations Message-ID: <20250107190855.2312210-4-ihor.solodrai@pm.me> In-Reply-To: <20250107190855.2312210-1-ihor.solodrai@pm.me> References: <20250107190855.2312210-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: 59602fb3a5d36b62714f0f51092f38d9311ed233 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alan Maguire Have saved function representation point back at immutable ELF function table. This will make sharing the ELF function table across encoders easier. Simply accumulate saved functions for each encoder, and on completion combine them into a name-sorted list. Then carry out comparisons to check for inconsistent representations, skipping functions that are inconsistent in their representation. /usr/bin/time samples with this change: jobs 1, mem 837844 Kb, time 6.40 sec jobs 2, mem 936204 Kb, time 3.88 sec jobs 4, mem 1023120 Kb, time 2.75 sec jobs 8, mem 1163824 Kb, time 2.31 sec jobs 16, mem 1190588 Kb, time 2.08 sec jobs 32, mem 1341180 Kb, time 2.36 sec /usr/bin/time samples on next (3ddadc1): jobs 1, mem 834100 Kb, time 6.20 sec jobs 2, mem 925048 Kb, time 3.81 sec jobs 4, mem 1025424 Kb, time 2.88 sec jobs 8, mem 1178480 Kb, time 2.21 sec jobs 16, mem 1241780 Kb, time 2.07 sec jobs 32, mem 1442316 Kb, time 2.33 sec Link: https://lore.kernel.org/dwarves/20241128012341.4081072-4-ihor.solodrai@pm.me/ Signed-off-by: Alan Maguire Co-developed-by: Ihor Solodrai Signed-off-by: Ihor Solodrai --- btf_encoder.c | 303 +++++++++++++++++++++++++++----------------------- btf_encoder.h | 1 + pahole.c | 2 + 3 files changed, 169 insertions(+), 137 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index 6720065..b1e80ca 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -72,14 +72,15 @@ struct btf_encoder_func_annot { /* state used to do later encoding of saved functions */ struct btf_encoder_func_state { + struct list_head node; + struct btf_encoder *encoder; + struct elf_function *elf; uint32_t type_id_off; uint16_t nr_parms; uint16_t nr_annots; - uint8_t initialized:1; uint8_t optimized_parms:1; uint8_t unexpected_reg:1; uint8_t inconsistent_proto:1; - uint8_t processed:1; int ret_type_id; struct btf_encoder_func_parm *parms; struct btf_encoder_func_annot *annots; @@ -89,7 +90,6 @@ struct elf_function { const char *name; char *alias; size_t prefixlen; - struct btf_encoder_func_state state; }; struct elf_secinfo { @@ -126,6 +126,7 @@ struct btf_encoder { struct elf_secinfo *secinfo; size_t seccnt; int encode_vars; + struct list_head func_states; struct { struct elf_function *entries; int allocated; @@ -148,8 +149,6 @@ struct btf_kfunc_set_range { 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. */ @@ -693,25 +692,26 @@ static int32_t btf_encoder__tag_type(struct btf_encoder *encoder, uint32_t tag_t } static int32_t btf_encoder__add_func_proto(struct btf_encoder *encoder, struct ftype *ftype, - struct elf_function *func) + struct btf_encoder_func_state *state) { - struct btf *btf = encoder->btf; const struct btf_type *t; + struct btf *btf; struct parameter *param; uint16_t nr_params, param_idx; int32_t id, type_id; char tmp_name[KSYM_NAME_LEN]; const char *name; - struct btf_encoder_func_state *state; - assert(ftype != NULL || func != NULL); + assert(ftype != NULL || state != NULL); /* add btf_type for func_proto */ if (ftype) { + btf = encoder->btf; nr_params = ftype->nr_parms + (ftype->unspec_parms ? 1 : 0); type_id = btf_encoder__tag_type(encoder, ftype->tag.type); - } else if (func) { - state = &func->state; + } else if (state) { + encoder = state->encoder; + btf = state->encoder->btf; nr_params = state->nr_parms; type_id = state->ret_type_id; } else { @@ -801,8 +801,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); @@ -1031,10 +1029,13 @@ static bool types__match(struct btf_encoder *encoder, return false; } -static bool funcs__match(struct btf_encoder *encoder, struct elf_function *func, - struct btf *btf1, struct btf_encoder_func_state *s1, - struct btf *btf2, struct btf_encoder_func_state *s2) +static bool funcs__match(struct btf_encoder_func_state *s1, + struct btf_encoder_func_state *s2) { + struct btf_encoder *encoder = s1->encoder; + struct elf_function *func = s1->elf; + struct btf *btf1 = s1->encoder->btf; + struct btf *btf2 = s2->encoder->btf; uint8_t i; if (s1->nr_parms != s2->nr_parms) { @@ -1072,8 +1073,7 @@ static bool funcs__match(struct btf_encoder *encoder, struct elf_function *func, static int32_t btf_encoder__save_func(struct btf_encoder *encoder, struct function *fn, struct elf_function *func) { - struct btf_encoder_func_state *existing = &func->state; - struct btf_encoder_func_state state = { 0 }; + struct btf_encoder_func_state *state = zalloc(sizeof(*state)); struct ftype *ftype = &fn->proto; struct btf *btf = encoder->btf; struct llvm_annotation *annot; @@ -1081,22 +1081,23 @@ static int32_t btf_encoder__save_func(struct btf_encoder *encoder, struct functi uint8_t param_idx = 0; int str_off, err = 0; - /* if already skipping this function, no need to proceed. */ - if (existing->unexpected_reg || existing->inconsistent_proto) - return 0; + if (!state) + return -ENOMEM; - state.nr_parms = ftype->nr_parms + (ftype->unspec_parms ? 1 : 0); - state.ret_type_id = ftype->tag.type == 0 ? 0 : encoder->type_id_off + ftype->tag.type; - if (state.nr_parms > 0) { - state.parms = zalloc(state.nr_parms * sizeof(*state.parms)); - if (!state.parms) { + state->encoder = encoder; + state->elf = func; + state->nr_parms = ftype->nr_parms + (ftype->unspec_parms ? 1 : 0); + state->ret_type_id = ftype->tag.type == 0 ? 0 : encoder->type_id_off + ftype->tag.type; + if (state->nr_parms > 0) { + state->parms = zalloc(state->nr_parms * sizeof(*state->parms)); + if (!state->parms) { err = -ENOMEM; goto out; } } - state.inconsistent_proto = ftype->inconsistent_proto; - state.unexpected_reg = ftype->unexpected_reg; - state.optimized_parms = ftype->optimized_parms; + state->inconsistent_proto = ftype->inconsistent_proto; + state->unexpected_reg = ftype->unexpected_reg; + state->optimized_parms = ftype->optimized_parms; ftype__for_each_parameter(ftype, param) { const char *name = parameter__name(param) ?: ""; @@ -1105,21 +1106,21 @@ static int32_t btf_encoder__save_func(struct btf_encoder *encoder, struct functi err = str_off; goto out; } - state.parms[param_idx].name_off = str_off; - state.parms[param_idx].type_id = param->tag.type == 0 ? 0 : - encoder->type_id_off + param->tag.type; + state->parms[param_idx].name_off = str_off; + state->parms[param_idx].type_id = param->tag.type == 0 ? 0 : + encoder->type_id_off + param->tag.type; param_idx++; } if (ftype->unspec_parms) - state.parms[param_idx].type_id = 0; + state->parms[param_idx].type_id = 0; list_for_each_entry(annot, &fn->annots, node) - state.nr_annots++; - if (state.nr_annots) { + state->nr_annots++; + if (state->nr_annots) { uint8_t idx = 0; - state.annots = zalloc(state.nr_annots * sizeof(*state.annots)); - if (!state.annots) { + state->annots = zalloc(state->nr_annots * sizeof(*state->annots)); + if (!state->annots) { err = -ENOMEM; goto out; } @@ -1129,46 +1130,24 @@ static int32_t btf_encoder__save_func(struct btf_encoder *encoder, struct functi err = str_off; goto out; } - state.annots[idx].value = str_off; - state.annots[idx].component_idx = annot->component_idx; + state->annots[idx].value = str_off; + state->annots[idx].component_idx = annot->component_idx; idx++; } } - state.initialized = 1; - - if (state.unexpected_reg) - btf_encoder__log_func_skip(encoder, func, - "unexpected register used for parameter\n"); - if (!existing->initialized) { - memcpy(existing, &state, sizeof(*existing)); - return 0; - } - - /* If saving and we find an existing entry, we want to merge - * observations across both functions, checking that the - * "seen optimized parameters", "inconsistent prototype" - * and "unexpected register" status is reflected in the - * func entry. - * If the entry is new, record encoder state required - * to add the local function later (encoder + type_id_off) - * such that we can add the function later. - */ - existing->optimized_parms |= state.optimized_parms; - existing->unexpected_reg |= state.unexpected_reg; - if (!existing->unexpected_reg && - !funcs__match(encoder, func, encoder->btf, &state, - encoder->btf, existing)) - existing->inconsistent_proto = 1; + list_add_tail(&state->node, &encoder->func_states); + return 0; out: - zfree(&state.annots); - zfree(&state.parms); + zfree(&state->annots); + zfree(&state->parms); + free(state); return err; } static int32_t btf_encoder__add_func(struct btf_encoder *encoder, - struct elf_function *func) + struct btf_encoder_func_state *state) { - struct btf_encoder_func_state *state = &func->state; + struct elf_function *func = state->elf; int btf_fnproto_id, btf_fn_id, tag_type_id = 0; int16_t component_idx = -1; const char *name; @@ -1176,7 +1155,7 @@ static int32_t btf_encoder__add_func(struct btf_encoder *encoder, char tmp_value[KSYM_NAME_LEN]; uint16_t idx; - btf_fnproto_id = btf_encoder__add_func_proto(encoder, NULL, func); + btf_fnproto_id = btf_encoder__add_func_proto(encoder, NULL, state); name = func->alias ?: func->name; if (btf_fnproto_id >= 0) btf_fn_id = btf_encoder__add_ref_type(encoder, BTF_KIND_FUNC, btf_fnproto_id, @@ -1214,62 +1193,6 @@ static int32_t btf_encoder__add_func(struct btf_encoder *encoder, return 0; } -static int btf_encoder__add_saved_funcs(struct btf_encoder *encoder) -{ - int i; - - for (i = 0; i < encoder->functions.cnt; i++) { - struct elf_function *func = &encoder->functions.entries[i]; - struct btf_encoder_func_state *state = &func->state; - struct btf_encoder *other_encoder = NULL; - - if (!state->initialized || state->processed) - continue; - /* merge optimized-out status across encoders; since each - * encoder has the same elf symbol table we can use the - * same index to access the same elf symbol. - */ - btf_encoders__for_each_encoder(other_encoder) { - struct elf_function *other_func; - struct btf_encoder_func_state *other_state; - uint8_t optimized, unexpected, inconsistent; - - if (other_encoder == encoder) - continue; - - other_func = &other_encoder->functions.entries[i]; - other_state = &other_func->state; - if (!other_state->initialized) - continue; - optimized = state->optimized_parms | other_state->optimized_parms; - unexpected = state->unexpected_reg | other_state->unexpected_reg; - inconsistent = state->inconsistent_proto | other_state->inconsistent_proto; - if (!unexpected && !inconsistent && - !funcs__match(encoder, func, - encoder->btf, state, - other_encoder->btf, other_state)) - inconsistent = 1; - state->optimized_parms = other_state->optimized_parms = optimized; - state->unexpected_reg = other_state->unexpected_reg = unexpected; - state->inconsistent_proto = other_state->inconsistent_proto = inconsistent; - - other_state->processed = 1; - } - /* do not exclude functions with optimized-out parameters; they - * may still be _called_ with the right parameter values, they - * just do not _use_ them. Only exclude functions with - * unexpected register use or multiple inconsistent prototypes. - */ - if (!encoder->skip_encoding_inconsistent_proto || - (!state->unexpected_reg && !state->inconsistent_proto)) { - if (btf_encoder__add_func(encoder, func)) - return -1; - } - state->processed = 1; - } - return 0; -} - static int functions_cmp(const void *_a, const void *_b) { const struct elf_function *a = _a; @@ -1297,6 +1220,116 @@ static void *reallocarray_grow(void *ptr, int *nmemb, size_t size) return new; } +static int saved_functions_cmp(const void *_a, const void *_b) +{ + struct btf_encoder_func_state * const *a = _a; + struct btf_encoder_func_state * const *b = _b; + + return functions_cmp((*a)->elf, (*b)->elf); +} + +static int saved_functions_combine(void *_a, void *_b) +{ + uint8_t optimized, unexpected, inconsistent; + struct btf_encoder_func_state *a = _a; + struct btf_encoder_func_state *b = _b; + int ret; + + ret = strncmp(a->elf->name, b->elf->name, + max(a->elf->prefixlen, b->elf->prefixlen)); + if (ret != 0) + return ret; + optimized = a->optimized_parms | b->optimized_parms; + unexpected = a->unexpected_reg | b->unexpected_reg; + inconsistent = a->inconsistent_proto | b->inconsistent_proto; + if (!unexpected && !inconsistent && !funcs__match(a, b)) + inconsistent = 1; + a->optimized_parms = b->optimized_parms = optimized; + a->unexpected_reg = b->unexpected_reg = unexpected; + a->inconsistent_proto = b->inconsistent_proto = inconsistent; + + return 0; +} + +static void btf_encoder__delete_saved_funcs(struct btf_encoder *encoder) +{ + struct btf_encoder_func_state *pos, *s; + + list_for_each_entry_safe(pos, s, &encoder->func_states, node) { + list_del(&pos->node); + free(pos->parms); + free(pos->annots); + free(pos); + } + + for (int i = 0; i < encoder->functions.cnt; i++) + free(encoder->functions.entries[i].alias); +} + +int btf_encoder__add_saved_funcs(struct btf_encoder *encoder) +{ + struct btf_encoder_func_state **saved_fns = NULL, *s; + int err = 0, i = 0, j, nr_saved_fns = 0; + struct btf_encoder *e = NULL; + + /* Retrieve function states from each encoder, combine them + * and sort by name, addr. + */ + btf_encoders__for_each_encoder(e) { + list_for_each_entry(s, &e->func_states, node) + nr_saved_fns++; + } + + if (nr_saved_fns == 0) + goto out; + + saved_fns = calloc(nr_saved_fns, sizeof(*saved_fns)); + if (!saved_fns) { + err = -ENOMEM; + goto out; + } + + btf_encoders__for_each_encoder(e) { + list_for_each_entry(s, &e->func_states, node) + saved_fns[i++] = s; + } + qsort(saved_fns, nr_saved_fns, sizeof(*saved_fns), saved_functions_cmp); + + for (i = 0; i < nr_saved_fns; i = j) { + struct btf_encoder_func_state *state = saved_fns[i]; + bool add_to_btf = !encoder->skip_encoding_inconsistent_proto; + + /* Compare across sorted functions that match by name/prefix; + * share inconsistent/unexpected reg state between them. + */ + j = i + 1; + + while (j < nr_saved_fns && saved_functions_combine(saved_fns[i], saved_fns[j]) == 0) + j++; + + /* do not exclude functions with optimized-out parameters; they + * may still be _called_ with the right parameter values, they + * just do not _use_ them. Only exclude functions with + * unexpected register use or multiple inconsistent prototypes. + */ + add_to_btf |= !state->unexpected_reg && !state->inconsistent_proto; + + if (add_to_btf) { + err = btf_encoder__add_func(state->encoder, state); + if (err < 0) + goto out; + } + } + +out: + free(saved_fns); + btf_encoders__for_each_encoder(e) { + btf_encoder__delete_saved_funcs(e); + } + + return err; +} + static int btf_encoder__collect_function(struct btf_encoder *encoder, GElf_Sym *sym) { struct elf_function *new; @@ -1330,6 +1363,8 @@ static int btf_encoder__collect_function(struct btf_encoder *encoder, GElf_Sym * encoder->functions.suffix_cnt++; encoder->functions.entries[encoder->functions.cnt].prefixlen = suffix - name; + } else { + encoder->functions.entries[encoder->functions.cnt].prefixlen = strlen(name); } encoder->functions.cnt++; return 0; @@ -2048,8 +2083,9 @@ 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); + err = btf_encoder__add_saved_funcs(encoder); + if (err < 0) + return err; for (shndx = 1; shndx < encoder->seccnt; shndx++) if (gobuffer__size(&encoder->secinfo[shndx].secinfo)) @@ -2351,6 +2387,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam encoder->need_index_type = false; encoder->array_index_id = 0; encoder->encode_vars = 0; + INIT_LIST_HEAD(&encoder->func_states); if (!conf_load->skip_encoding_btf_vars) encoder->encode_vars |= BTF_VAR_PERCPU; if (conf_load->encode_btf_global_vars) @@ -2435,16 +2472,8 @@ out_delete: return NULL; } -void btf_encoder__delete_func(struct elf_function *func) -{ - free(func->alias); - zfree(&func->state.annots); - zfree(&func->state.parms); -} - void btf_encoder__delete(struct btf_encoder *encoder) { - int i; size_t shndx; if (encoder == NULL) @@ -2460,12 +2489,12 @@ void btf_encoder__delete(struct btf_encoder *encoder) encoder->btf = NULL; elf_symtab__delete(encoder->symtab); - for (i = 0; i < encoder->functions.cnt; i++) - btf_encoder__delete_func(&encoder->functions.entries[i]); encoder->functions.allocated = encoder->functions.cnt = 0; free(encoder->functions.entries); encoder->functions.entries = NULL; + btf_encoder__delete_saved_funcs(encoder); + free(encoder); } diff --git a/btf_encoder.h b/btf_encoder.h index 824963b..9b26162 100644 --- a/btf_encoder.h +++ b/btf_encoder.h @@ -33,5 +33,6 @@ 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 *encoder); #endif /* _BTF_ENCODER_H_ */ diff --git a/pahole.c b/pahole.c index fa5d8c7..a36b732 100644 --- a/pahole.c +++ b/pahole.c @@ -3185,6 +3185,7 @@ static int pahole_threads_collect(struct conf_load *conf, int nr_threads, void * if (error) goto out; + btf_encoder__add_saved_funcs(btf_encoder); for (i = 0; i < nr_threads; i++) { /* * Merge content of the btf instances of worker threads to the btf @@ -3843,6 +3844,7 @@ try_sole_arg_as_class_names: } err = btf_encoder__encode(btf_encoder); + btf_encoder__delete(btf_encoder); if (err) { fputs("Failed to encode BTF\n", stderr); goto out_cus_delete; From patchwork Tue Jan 7 19:09:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13929528 Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) (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 DD43F1F471C for ; Tue, 7 Jan 2025 19:09:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.31 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276971; cv=none; b=nO+/gDI7UsBFi27mC8j3jPHc33i6VTnaNFLQMYXKWtYRGJNBPwOwiMR2ni+lAK/gZgOahnnLqkEAIt3Lh4y3HRCEEL2Dk9d7viAtw6q6qvXrUShwrAMKgE3nt4NnNjmgy700llWVfqsu3NFJr6WCiKJ3lEBvf4rlmb8TAeDTKVw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276971; c=relaxed/simple; bh=C46zV9NDFhHlLiu9SgGgypRvrNUR490I9O6XG9hqIho=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CiJsjH5UNQPi/gQLtYKJcfJI1xLoJulECMjXMqmBzFjJ61JuL5tdsL68J3S1c0Xsn/TdQyg+63oq4imeFUZqYFALIgcH3+LQmhf0J0r9SACHTclVeIQN1EgUyPHa1PgRr8uhbZpFeHYyDG8d7GkcqaCsdJqZC1+aRnpP5IMjsdY= 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=INbbqOua; arc=none smtp.client-ip=79.135.106.31 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="INbbqOua" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736276967; x=1736536167; bh=N30LZya76BUReVoXzWhBm1uVU1iK80c4clCXBDnCfZc=; 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=INbbqOuaPiPcDTjwzfFRkqmAqBWkhNjq38SumEjDMGyxVoiMIc3DeO65Eja4d1w6h ktZT1Xh6QrAnbZe9gyvnwgawBC1LwFDS08M9yFp25s4GCQYE8D9eeZO0RdwHboyrgl MrYku/fy51BE6KFkfsE+dxA+MSce3ZfVVlICahL+Q2wsMxAUEEXk1RlJTQtaOGlUa8 z4c37sp2b9TdBsheD7fmszP16017GesRbyupF+DnU3fbGGhK3SJVi+KW+axFoYItT2 mKRR/BLUrP9Yi68XdkkAFvm6mxYTqsYKsY7SfcBy10EMikHO6yVAAcWu5cAARS/ufw CUyriP4hJ+TnQ== Date: Tue, 07 Jan 2025 19:09:21 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 04/10] btf_encoder: introduce elf_functions struct type Message-ID: <20250107190855.2312210-5-ihor.solodrai@pm.me> In-Reply-To: <20250107190855.2312210-1-ihor.solodrai@pm.me> References: <20250107190855.2312210-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: d3ffbb93f855276d2b969a14a0362dd3b79f2673 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Extract elf_functions struct type from btf_encoder. Replace routines operating on functions table in btf_encoder by routines operating on elf_functions: - btf_encoder__collect_function -> elf_functions__collect_function - btf_encoder__collect_symbols -> elf_functions__collect Now these functions do not depend on btf_encoder being passed to them as a parameter. Link: https://lore.kernel.org/dwarves/3MqWfdjBO9srtpr8kjweJgCkdwYKV6JC_-SN27S8Y9_J1SzssIgZs4Ptc5tEqpZ7w2vbSmTQ35J5CX35Yb4KMbw8wsTrB2IAf2SWU-k4Xi4=@pm.me/ Link: https://lore.kernel.org/dwarves/20241128012341.4081072-6-ihor.solodrai@pm.me/ Acked-by: Eduard Zingerman Signed-off-by: Ihor Solodrai --- btf_encoder.c | 118 ++++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index b1e80ca..0df9296 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -101,6 +101,13 @@ struct elf_secinfo { struct gobuffer secinfo; }; +struct elf_functions { + struct elf_symtab *symtab; + struct elf_function *entries; + int cnt; + int suffix_cnt; /* number of .isra, .part etc */ +}; + /* * cu: cu being processed. */ @@ -127,12 +134,7 @@ struct btf_encoder { size_t seccnt; int encode_vars; struct list_head func_states; - struct { - struct elf_function *entries; - int allocated; - int cnt; - int suffix_cnt; /* number of .isra, .part etc */ - } functions; + struct elf_functions functions; }; struct btf_func { @@ -1210,16 +1212,6 @@ static int functions_cmp(const void *_a, const void *_b) #define max(x, y) ((x) < (y) ? (y) : (x)) #endif -static void *reallocarray_grow(void *ptr, int *nmemb, size_t size) -{ - int new_nmemb = max(1000, *nmemb * 3 / 2); - void *new = realloc(ptr, new_nmemb * size); - - if (new) - *nmemb = new_nmemb; - return new; -} - static int saved_functions_cmp(const void *_a, const void *_b) { struct btf_encoder_func_state * const *a = _a; @@ -1330,44 +1322,30 @@ out: return err; } -static int btf_encoder__collect_function(struct btf_encoder *encoder, GElf_Sym *sym) +static void elf_functions__collect_function(struct elf_functions *functions, GElf_Sym *sym) { - struct elf_function *new; + struct elf_function *func; const char *name; if (elf_sym__type(sym) != STT_FUNC) - return 0; - name = elf_sym__name(sym, encoder->symtab); - if (!name) - return 0; + return; - if (encoder->functions.cnt == encoder->functions.allocated) { - new = reallocarray_grow(encoder->functions.entries, - &encoder->functions.allocated, - sizeof(*encoder->functions.entries)); - if (!new) { - /* - * The cleanup - delete_functions is called - * in btf_encoder__encode_cu error path. - */ - return -1; - } - encoder->functions.entries = new; - } + name = elf_sym__name(sym, functions->symtab); + if (!name) + return; - memset(&encoder->functions.entries[encoder->functions.cnt], 0, - sizeof(*new)); - encoder->functions.entries[encoder->functions.cnt].name = name; + func = &functions->entries[functions->cnt]; + func->name = name; if (strchr(name, '.')) { const char *suffix = strchr(name, '.'); - encoder->functions.suffix_cnt++; - encoder->functions.entries[encoder->functions.cnt].prefixlen = suffix - name; + functions->suffix_cnt++; + func->prefixlen = suffix - name; } else { - encoder->functions.entries[encoder->functions.cnt].prefixlen = strlen(name); + func->prefixlen = strlen(name); } - encoder->functions.cnt++; - return 0; + + functions->cnt++; } static struct elf_function *btf_encoder__find_function(const struct btf_encoder *encoder, @@ -2139,26 +2117,53 @@ int btf_encoder__encode(struct btf_encoder *encoder) return err; } - -static int btf_encoder__collect_symbols(struct btf_encoder *encoder) +static int elf_functions__collect(struct elf_functions *functions) { - uint32_t sym_sec_idx; + uint32_t nr_symbols = elf_symtab__nr_symbols(functions->symtab); + struct elf_function *tmp; + Elf32_Word sym_sec_idx; uint32_t core_id; GElf_Sym sym; + int err = 0; - elf_symtab__for_each_symbol_index(encoder->symtab, core_id, sym, sym_sec_idx) { - if (btf_encoder__collect_function(encoder, &sym)) - return -1; + /* We know that number of functions is less than number of symbols, + * so we can overallocate temporarily. + */ + functions->entries = calloc(nr_symbols, sizeof(*functions->entries)); + if (!functions->entries) { + err = -ENOMEM; + goto out_free; } - if (encoder->functions.cnt) { - qsort(encoder->functions.entries, encoder->functions.cnt, sizeof(encoder->functions.entries[0]), - functions_cmp); - if (encoder->verbose) - printf("Found %d functions!\n", encoder->functions.cnt); + functions->cnt = 0; + elf_symtab__for_each_symbol_index(functions->symtab, core_id, sym, sym_sec_idx) { + elf_functions__collect_function(functions, &sym); + } + + if (functions->cnt) { + qsort(functions->entries, functions->cnt, sizeof(*functions->entries), functions_cmp); + } else { + err = 0; + goto out_free; + } + + /* Reallocate to the exact size */ + tmp = realloc(functions->entries, functions->cnt * sizeof(struct elf_function)); + if (tmp) { + functions->entries = tmp; + } else { + fprintf(stderr, "could not reallocate memory for elf_functions table\n"); + err = -ENOMEM; + goto out_free; } return 0; + +out_free: + free(functions->entries); + functions->entries = NULL; + functions->cnt = 0; + return err; } static bool ftype__has_arg_names(const struct ftype *ftype) @@ -2419,6 +2424,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; /* index the ELF sections for later lookup */ @@ -2457,7 +2463,7 @@ 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 (btf_encoder__collect_symbols(encoder)) + if (elf_functions__collect(&encoder->functions)) goto out_delete; if (encoder->verbose) @@ -2489,7 +2495,7 @@ void btf_encoder__delete(struct btf_encoder *encoder) encoder->btf = NULL; elf_symtab__delete(encoder->symtab); - encoder->functions.allocated = encoder->functions.cnt = 0; + encoder->functions.cnt = 0; free(encoder->functions.entries); encoder->functions.entries = NULL; From patchwork Tue Jan 7 19:09:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13929531 Received: from mail-40133.protonmail.ch (mail-40133.protonmail.ch [185.70.40.133]) (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 353701F4E58 for ; Tue, 7 Jan 2025 19:09:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.40.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276983; cv=none; b=SGttuvZFpiExruyqAlJr7Dwj9/Ihg7DCBTdcuNKJgImpUzn8AbWjPJdPGF90EcFXR9VeycJXC+ig7WoHCL7tNnU2m0l5oHuNnIS9E7/x4B57MutbVR//enwVDPtGOArBXMpr94XeGaYL6QUDczVFG+UyPBXqSYVjf9EwdQZklRE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276983; c=relaxed/simple; bh=AnJvG5KV1CDh+Sa9FGvR9/U+9MhmvmAU6SUN9SlHepc=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=naDDtd72FqpdwE13DPbq4P3mPdf7UqazUrxsbE62XjWh7Zlt9YvYHTVyKrH0wopPqab8U8xANsi3pxB+C1MQ9EZhnjeb5xp10M0KRfqm1VdtbeyligUSRuCQwXaStftdsEQi1MFp5SvNJ1mlHgYbfWQC3mP6AvH9xCRps60EntM= 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=Q38RzQm/; arc=none smtp.client-ip=185.70.40.133 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="Q38RzQm/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736276971; x=1736536171; bh=jthM5smHq8dNblzxlWEmNR5plcMJ00uxZ5HlZ6RKUPI=; 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=Q38RzQm/JL/kS1exixmwRTLhjjyWPoZQ83la7NdbvrQGyDiT12LXHqEQNGTYRf7Vt 5OECJLs1KYgz0fLkGxeLtyh8Gw0XJo21wWjpivCXpxNBn6uc/sjmBIkDstqm1hYnTO O7BQBLceP1p9OUXNEPVGNmq+VT3Djoa0/C8g1kIU/1juRVcY9K0cv04ZbXtSSZlq7+ GQfsrQUTIESI7d28I0KZla6qVatDxkerTgR1vyToqjn8I62stA0rnAM6q5DRHIcHVI QG4Y1fYnYCLBWMPAQ7Z6BMMeR5D+ej3SCuQiHHvlXL1yCcTKPb/vHbMt4mRrL7P3zD vkGZ/1FsI7PFA== Date: Tue, 07 Jan 2025 19:09:27 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 05/10] btf_encoder: introduce elf_functions_list Message-ID: <20250107190855.2312210-6-ihor.solodrai@pm.me> In-Reply-To: <20250107190855.2312210-1-ihor.solodrai@pm.me> References: <20250107190855.2312210-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: 7706a4e7e958c8f792862b8e38a17f4af43d2d60 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 In case of processing of multiple DWARF modules, multiple ELFs are read. This requires maintaining and elf_functions table per ELF. Replace btf_encoder.functions with btf_encoder.elf_functions_list, that contains all necessary elf_functions tables. The list is initialized when btf_encoder is created. When a new CU is assigned to the encoder in btf_encoder__encode_cu, an elf_functions table will be created if the CU is coming from an unknown Elf. This patch is a variant of [1], following a discussion at [2]. [1] https://lore.kernel.org/bpf/20241213223641.564002-7-ihor.solodrai@pm.me/ [2] https://lore.kernel.org/bpf/C82bYTvJaV4bfT15o25EsBiUvFsj5eTlm17933Hvva76CXjIcu3gvpaOCWPgeZ8g3cZ-RMa8Vp0y1o_QMR2LhPB-LEUYfZCGuCfR_HvkIP8=@pm.me/ Signed-off-by: Ihor Solodrai --- btf_encoder.c | 138 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 115 insertions(+), 23 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index 0df9296..7b4523b 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -102,6 +102,8 @@ struct elf_secinfo { }; struct elf_functions { + struct list_head node; /* for elf_functions_list */ + Elf *elf; /* source ELF */ struct elf_symtab *symtab; struct elf_function *entries; int cnt; @@ -134,7 +136,11 @@ struct btf_encoder { size_t seccnt; int encode_vars; struct list_head func_states; - struct elf_functions functions; + /* This is a list of elf_functions tables, one per ELF. + * Multiple ELF modules can be processed in one pahole run, + * so we have to store elf_functions tables per ELF. + */ + struct list_head elf_functions_list; }; struct btf_func { @@ -148,6 +154,72 @@ struct btf_kfunc_set_range { uint64_t end; }; +static inline void elf_functions__delete(struct elf_functions *funcs) +{ + for (int i = 0; i < funcs->cnt; i++) + free(funcs->entries[i].alias); + free(funcs->entries); + elf_symtab__delete(funcs->symtab); + list_del(&funcs->node); + free(funcs); +} + +static int elf_functions__collect(struct elf_functions *functions); + +struct elf_functions *elf_functions__new(Elf *elf) +{ + struct elf_functions *funcs; + int err; + + funcs = calloc(1, sizeof(*funcs)); + if (!funcs) { + err = -ENOMEM; + goto out_delete; + } + + funcs->symtab = elf_symtab__new(NULL, elf); + if (!funcs->symtab) { + err = -1; + goto out_delete; + } + + funcs->elf = elf; + err = elf_functions__collect(funcs); + if (err < 0) + goto out_delete; + + return funcs; + +out_delete: + elf_functions__delete(funcs); + return NULL; +} + +static inline void elf_functions_list__clear(struct list_head *elf_functions_list) +{ + struct elf_functions *funcs; + struct list_head *pos, *tmp; + + list_for_each_safe(pos, tmp, elf_functions_list) { + funcs = list_entry(pos, struct elf_functions, node); + elf_functions__delete(funcs); + } +} + +static struct elf_functions *elf_functions__find(const Elf *elf, const struct list_head *elf_functions_list) +{ + struct elf_functions *funcs; + struct list_head *pos; + + list_for_each(pos, elf_functions_list) { + funcs = list_entry(pos, struct elf_functions, node); + if (funcs->elf == elf) + return funcs; + } + return NULL; +} + + static LIST_HEAD(encoders); static pthread_mutex_t encoders__lock = PTHREAD_MUTEX_INITIALIZER; @@ -1253,9 +1325,6 @@ static void btf_encoder__delete_saved_funcs(struct btf_encoder *encoder) free(pos->annots); free(pos); } - - for (int i = 0; i < encoder->functions.cnt; i++) - free(encoder->functions.entries[i].alias); } int btf_encoder__add_saved_funcs(struct btf_encoder *encoder) @@ -1348,12 +1417,30 @@ static void elf_functions__collect_function(struct elf_functions *functions, GEl functions->cnt++; } +static struct elf_functions *btf_encoder__elf_functions(struct btf_encoder *encoder) +{ + struct elf_functions *funcs = NULL; + + if (!encoder->cu || !encoder->cu->elf) + return NULL; + + funcs = elf_functions__find(encoder->cu->elf, &encoder->elf_functions_list); + if (!funcs) { + funcs = elf_functions__new(encoder->cu->elf); + if (funcs) + list_add(&funcs->node, &encoder->elf_functions_list); + } + + return funcs; +} + static struct elf_function *btf_encoder__find_function(const struct btf_encoder *encoder, const char *name, size_t prefixlen) { + struct elf_functions *funcs = elf_functions__find(encoder->cu->elf, &encoder->elf_functions_list); struct elf_function key = { .name = name, .prefixlen = prefixlen }; - return bsearch(&key, encoder->functions.entries, encoder->functions.cnt, sizeof(key), functions_cmp); + return bsearch(&key, funcs->entries, funcs->cnt, sizeof(key), functions_cmp); } static bool btf_name_char_ok(char c, bool first) @@ -2114,6 +2201,8 @@ int btf_encoder__encode(struct btf_encoder *encoder) #endif err = btf_encoder__write_elf(encoder, encoder->btf, BTF_ELF_SEC); } + + elf_functions_list__clear(&encoder->elf_functions_list); return err; } @@ -2369,8 +2458,10 @@ out: struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filename, struct btf *base_btf, bool verbose, struct conf_load *conf_load) { struct btf_encoder *encoder = zalloc(sizeof(*encoder)); + struct elf_functions *funcs = NULL; if (encoder) { + encoder->cu = cu; encoder->raw_output = detached_filename != NULL; encoder->source_filename = strdup(cu->filename); encoder->filename = strdup(encoder->raw_output ? detached_filename : cu->filename); @@ -2398,6 +2489,13 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam if (conf_load->encode_btf_global_vars) encoder->encode_vars |= BTF_VAR_GLOBAL; + INIT_LIST_HEAD(&encoder->elf_functions_list); + funcs = btf_encoder__elf_functions(encoder); + if (!funcs) + goto out_delete; + + encoder->symtab = funcs->symtab; + GElf_Ehdr ehdr; if (gelf_getehdr(cu->elf, &ehdr) == NULL) { @@ -2418,14 +2516,6 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam goto out_delete; } - encoder->symtab = elf_symtab__new(NULL, cu->elf); - if (!encoder->symtab) { - if (encoder->verbose) - printf("%s: '%s' doesn't have symtab.\n", __func__, cu->filename); - goto out; - } - encoder->functions.symtab = encoder->symtab; - /* index the ELF sections for later lookup */ GElf_Shdr shdr; @@ -2463,14 +2553,11 @@ 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); } -out: + return encoder; out_delete: @@ -2493,11 +2580,8 @@ void btf_encoder__delete(struct btf_encoder *encoder) zfree(&encoder->source_filename); btf__free(encoder->btf); encoder->btf = NULL; - elf_symtab__delete(encoder->symtab); - encoder->functions.cnt = 0; - free(encoder->functions.entries); - encoder->functions.entries = NULL; + elf_functions_list__clear(&encoder->elf_functions_list); btf_encoder__delete_saved_funcs(encoder); @@ -2508,12 +2592,20 @@ int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct co { struct llvm_annotation *annot; int btf_type_id, tag_type_id, skipped_types = 0; + struct elf_functions *funcs; uint32_t core_id; struct function *fn; struct tag *pos; int err = 0; encoder->cu = cu; + funcs = btf_encoder__elf_functions(encoder); + if (!funcs) { + err = -1; + goto out; + } + encoder->symtab = funcs->symtab; + encoder->type_id_off = btf__type_cnt(encoder->btf) - 1; if (!encoder->has_index_type) { @@ -2597,7 +2689,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 (funcs->cnt) { const char *name; name = function__name(fn); @@ -2606,7 +2698,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); - if (!func && encoder->functions.suffix_cnt && + if (!func && funcs->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 From patchwork Tue Jan 7 19:09:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13929530 Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) (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 89C891F4710 for ; Tue, 7 Jan 2025 19:09:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.31 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276982; cv=none; b=mC9CEekdRMoghr4y4gTWEnPB54RnyYLuFiO/QQuBZ06t05bND9ePHmrE01tmisaBymbIPPuDLnqqkOMvhNa+iVnV/5a6lL9kJoI5A4eg68lSssP+8mwzRuL0clkuYsa34XITxrhxGq4z+kATnABQIGOHw1C9Dtmau6NCT/lODi0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276982; c=relaxed/simple; bh=sdehCcje+opowFDMp/Ilx40UpCuq0VZkGfeORqRinMw=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=madcWBMR3tgs4PlLTkryKdk1YGy22KrfC+f6aq3UyT1iSt7aE964U/VNbU5BYxXHFL638hxO6A3Uk5BDLuYnGkVzASY29rrUEzjQY1Mum+/hAfK8QTIww3Kmm+Zd0eioC9ZZiySDW54OB5r/3bJ4s2fkuTyAVsD3qwIFcX6AIa4= 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=GjF8W9zO; arc=none smtp.client-ip=79.135.106.31 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="GjF8W9zO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736276978; x=1736536178; bh=QUtmwT64ALJrJ4hzLZ830aIqcDu2BdhXwL69XnC87Pg=; 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=GjF8W9zO8LzZWk5Kd80m+PFAOqAhj5DDK+wHIC/NNhX2R+1WRAi2GrMTYNiXIlig/ O2uuU5peHtHWMkh7Z62ErkdNq8vsl+8Jz9GzvlxaM1dds8JLZTP01oIBhm35wMSwYS /rBUGepkeiWB76lcV4RjIMtcu4oF1axvMZXL1vbnugmz4O+VbABxmkS+nLTzGxrDPa 5vUF2fIY0FgCySRtNHxUGuZ89fKNxQil+Dc0T5RbrSzZs7mnPvD9zdcre6qyEn4AEV T0Ee2utN2gB/qQrjG8l/T4LbPfncQ/GslFtU4T2sjf+dmZsrCrMPdu33mxQ4UAjzn8 MZ2dx3sxwysgQ== Date: Tue, 07 Jan 2025 19:09:32 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 06/10] btf_encoder: remove skip_encoding_inconsistent_proto Message-ID: <20250107190855.2312210-7-ihor.solodrai@pm.me> In-Reply-To: <20250107190855.2312210-1-ihor.solodrai@pm.me> References: <20250107190855.2312210-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: 8b9647ae7ce26096ed20e01c7a3179701822d1b1 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This flag is needed only for btf_encoder__add_saved_funcs(), so there is no reason to keep it in each btf_encoder. Link: https://lore.kernel.org/dwarves/e1df45360963d265ea5e0b3634f0a3dae0c9c343.camel@gmail.com/ Signed-off-by: Ihor Solodrai --- btf_encoder.c | 10 ++++------ btf_encoder.h | 4 ++-- pahole.c | 7 +++++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index 7b4523b..875ec9d 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -128,7 +128,6 @@ struct btf_encoder { force, gen_floats, skip_encoding_decl_tag, - skip_encoding_inconsistent_proto, tag_kfuncs, gen_distilled_base; uint32_t array_index_id; @@ -1327,7 +1326,7 @@ static void btf_encoder__delete_saved_funcs(struct btf_encoder *encoder) } } -int btf_encoder__add_saved_funcs(struct btf_encoder *encoder) +int btf_encoder__add_saved_funcs(bool skip_encoding_inconsistent_proto) { struct btf_encoder_func_state **saved_fns = NULL, *s; int err = 0, i = 0, j, nr_saved_fns = 0; @@ -1358,7 +1357,7 @@ int btf_encoder__add_saved_funcs(struct btf_encoder *encoder) for (i = 0; i < nr_saved_fns; i = j) { struct btf_encoder_func_state *state = saved_fns[i]; - bool add_to_btf = !encoder->skip_encoding_inconsistent_proto; + bool add_to_btf = !skip_encoding_inconsistent_proto; /* Compare across sorted functions that match by name/prefix; * share inconsistent/unexpected reg state between them. @@ -2142,13 +2141,13 @@ out: return err; } -int btf_encoder__encode(struct btf_encoder *encoder) +int btf_encoder__encode(struct btf_encoder *encoder, struct conf_load *conf) { bool should_tag_kfuncs; int err; size_t shndx; - err = btf_encoder__add_saved_funcs(encoder); + err = btf_encoder__add_saved_funcs(conf->skip_encoding_btf_inconsistent_proto); if (err < 0) return err; @@ -2475,7 +2474,6 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam encoder->force = conf_load->btf_encode_force; encoder->gen_floats = conf_load->btf_gen_floats; encoder->skip_encoding_decl_tag = conf_load->skip_encoding_btf_decl_tag; - encoder->skip_encoding_inconsistent_proto = conf_load->skip_encoding_btf_inconsistent_proto; encoder->tag_kfuncs = conf_load->btf_decl_tag_kfuncs; encoder->gen_distilled_base = conf_load->btf_gen_distilled_base; encoder->verbose = verbose; diff --git a/btf_encoder.h b/btf_encoder.h index 9b26162..b95f2f3 100644 --- a/btf_encoder.h +++ b/btf_encoder.h @@ -26,13 +26,13 @@ enum btf_var_option { struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filename, struct btf *base_btf, bool verbose, struct conf_load *conf_load); void btf_encoder__delete(struct btf_encoder *encoder); -int btf_encoder__encode(struct btf_encoder *encoder); +int btf_encoder__encode(struct btf_encoder *encoder, struct conf_load *conf); int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct conf_load *conf_load); 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 *encoder); +int btf_encoder__add_saved_funcs(bool skip_encoding_inconsistent_proto); #endif /* _BTF_ENCODER_H_ */ diff --git a/pahole.c b/pahole.c index a36b732..37d76b1 100644 --- a/pahole.c +++ b/pahole.c @@ -3185,7 +3185,10 @@ static int pahole_threads_collect(struct conf_load *conf, int nr_threads, void * if (error) goto out; - btf_encoder__add_saved_funcs(btf_encoder); + err = btf_encoder__add_saved_funcs(conf_load.skip_encoding_btf_inconsistent_proto); + if (err < 0) + goto out; + for (i = 0; i < nr_threads; i++) { /* * Merge content of the btf instances of worker threads to the btf @@ -3843,7 +3846,7 @@ try_sole_arg_as_class_names: exit(1); } - err = btf_encoder__encode(btf_encoder); + err = btf_encoder__encode(btf_encoder, &conf_load); btf_encoder__delete(btf_encoder); if (err) { fputs("Failed to encode BTF\n", stderr); From patchwork Tue Jan 7 19:09:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13929532 Received: from mail-40134.protonmail.ch (mail-40134.protonmail.ch [185.70.40.134]) (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 973021F5403 for ; Tue, 7 Jan 2025 19:09:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.40.134 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276986; cv=none; b=stEVBhShrKMnBT1JFXIL2feljs0JJFwoF3Rv6T09tceVBaLdBxO0zAetqcVdFOzu4eQz1SaxZ03FDlTYJw/5P9fCfKmptSGZcqt/CAHUzDcmRfe0O4u/EoSCAxTqlNjhGFWwEI5Qw0uE01yBWuK7lz2fCgxlLW6UISbj4VH/XPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276986; c=relaxed/simple; bh=7ovS2eeLPplqA/W3FmMin2daJhx7VohmQwMMXiEQ+RM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=udPYkKhhW3vSu82E3Rhpt3IJLRAzV03BnBlEtTfEIJkyYF2EBdhXvcrV9fa+cnH1pXKnBytYILfabUWaDhAh20B6mKsHrfhilXrFVkCCn9acENzMuU6kADuIrPe5LYSr6jcdtBxAdcHfEpp2MynmI1eUxSEw8921skA69OZHZbo= 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=cCWoExFi; arc=none smtp.client-ip=185.70.40.134 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="cCWoExFi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736276980; x=1736536180; bh=BHoWOF28SwETmN/kPdJjiJ0vWid8McdO7im7Usp3iGQ=; 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=cCWoExFiL8pOSn5TAIx8I2Xaa4Rj0Mj/+L5dnAe1lWD5NZzfq9sFURKr4fsZmHyvj RG62z/HqwteyIs2c1USS/OcTk2JLDugXoRXiYFStTNTyoLgcN4Fxf8noJP8p4bHqlZ 76vQcmuAl+YCTdXb5KXZQcEjW5kb1YbIo992/17eISkkvIRIEziuD2OpY+UvkXmBS+ 32+z3cPGV1X4duXGp+LobSC1eB+SMkLJbrXsP+r2zJZhiVZzqESFKt8FObCRV1cZzR rrpt+JwzhtU81pU7YjUyjLmJG5+TfVscfstRvNcRcnup89mutVeJMZs0A4kSrKxGb6 X2bRUOt7CsZEA== Date: Tue, 07 Jan 2025 19:09:37 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 07/10] dwarf_loader: introduce cu->id Message-ID: <20250107190855.2312210-8-ihor.solodrai@pm.me> In-Reply-To: <20250107190855.2312210-1-ihor.solodrai@pm.me> References: <20250107190855.2312210-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: b403eedb1f6b467aab56613f796ce5d531955bb8 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add an id member to the struct cu. An id is an index of a CU, in order they are created in dwarf_loader.c This allows for an easy identification of a CU, particularly when they need to be processed in order. Signed-off-by: Ihor Solodrai --- dwarf_loader.c | 5 +++++ dwarves.h | 1 + 2 files changed, 6 insertions(+) diff --git a/dwarf_loader.c b/dwarf_loader.c index 34376b2..39e4cba 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -3440,6 +3440,7 @@ struct dwarf_cus { int build_id_len; int error; struct dwarf_cu *type_dcu; + uint32_t nr_cus_created; }; struct dwarf_thread { @@ -3472,6 +3473,9 @@ static struct dwarf_cu *dwarf_cus__create_cu(struct dwarf_cus *dcus, Dwarf_Die * cu->priv = dcu; cu->dfops = &dwarf__ops; + cu->id = dcus->nr_cus_created; + dcus->nr_cus_created++; + return dcu; } @@ -3783,6 +3787,7 @@ static int cus__load_module(struct cus *cus, struct conf_load *conf, .type_dcu = type_cu ? &type_dcu : NULL, .build_id = build_id, .build_id_len = build_id_len, + .nr_cus_created = 0, }; res = dwarf_cus__process_cus(&dcus); } diff --git a/dwarves.h b/dwarves.h index 0a4d5a2..b28a66e 100644 --- a/dwarves.h +++ b/dwarves.h @@ -290,6 +290,7 @@ struct cu { struct ptr_table functions_table; struct ptr_table tags_table; struct rb_root functions; + uint32_t id; const char *name; char *filename; void *priv; From patchwork Tue Jan 7 19:09:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13929534 Received: from mail-10628.protonmail.ch (mail-10628.protonmail.ch [79.135.106.28]) (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 C0CC01F470C for ; Tue, 7 Jan 2025 19:09:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.28 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276998; cv=none; b=UYcjEpj19D19nJGclaaIVMINf1yX2+mUSqy9WNiDabxBVdPsw0Hh08qMQATMvyjjNR6tjVdb24duuV5fku3F+qNK8ZRlTc8voXL43MsX4RAdlcOhtbeN4iCxHsZuGVjn3seixsKIs3rext4h41NCrixsQsIRPaaJHWGNk32tGek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736276998; c=relaxed/simple; bh=9IeFZzMnVRUUbyUt7fLv61oIiHiC1M36VosCjsne8Cs=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fM8PYhgbsrXObaGH5tp4ZiZgIOm0iUy1feT9JZ94XYl0o73Jd3aK69MzpJycGgVybbFtIbf5n+HRdFkapi+BBd8JSrxu/7VPn202KjMttnr02IfAPpH5cEa0GPINeyp1wgND/40Opl+WytJrJ6hBxIdrMmo/V8GhjCtx2J51Nw8= 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=Jf6RQghi; arc=none smtp.client-ip=79.135.106.28 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="Jf6RQghi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736276992; x=1736536192; bh=VeQTSyx/mjaHmdLYSH5yxPaGXWhYyevT098OP7Y4JnA=; 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=Jf6RQghi1Ux8zy9GqVZXvpYvijaM7gehiT1TLpuhZeLiJ7bIHoe9Kl7fZj9YXZuzz rLAGchitP1g9nC5XMOC5g7hfBBfp6yCofNscZ7LTXPwQ2s/rdsOK/tKUaT5WBXZhgv 0DyaH27e1oOsmScAKUIH5JiPtHDAqlU8O7zbItfRne2kgC0nSNOTIUGtqLuMHZ8g34 edPzsPcTea/C5rt1VcZhipMI6H6LQ6eCY06ly4oWrOHAmXR4SW9P8TZJyFecY+iZ9N HgeY1Y9JJn/v657G7V8AD+VZxm2ImXqqv6xQ0grdX8NUjoFW2+cXttfu0w7ifpNf6u ZpNYZy8XtJdYA== Date: Tue, 07 Jan 2025 19:09:48 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 09/10] btf_encoder: clean up global encoders list Message-ID: <20250107190855.2312210-10-ihor.solodrai@pm.me> In-Reply-To: <20250107190855.2312210-1-ihor.solodrai@pm.me> References: <20250107190855.2312210-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: 6f70ca2a186137f3dca0e61bdde6a5bfcd51ef32 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 With multithreading moved entirely to the dwarf_loader, now there is only one btf_encoder. Hence there is no need to maintain a global list of encoders anymore. Signed-off-by: Ihor Solodrai --- btf_encoder.c | 94 +++++---------------------------------------------- btf_encoder.h | 4 --- 2 files changed, 8 insertions(+), 90 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index 7fc04cb..4b6e4b7 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -218,39 +218,6 @@ static struct elf_functions *elf_functions__find(const Elf *elf, const struct li return NULL; } - -static LIST_HEAD(encoders); -static pthread_mutex_t encoders__lock = PTHREAD_MUTEX_INITIALIZER; - -/* mutex only needed for add/delete, as this can happen in multiple encoding - * threads. Traversal of the list is currently confined to thread collection. - */ - -#define btf_encoders__for_each_encoder(encoder) \ - list_for_each_entry(encoder, &encoders, node) - -static void btf_encoders__add(struct btf_encoder *encoder) -{ - pthread_mutex_lock(&encoders__lock); - list_add_tail(&encoder->node, &encoders); - pthread_mutex_unlock(&encoders__lock); -} - -static void btf_encoders__delete(struct btf_encoder *encoder) -{ - struct btf_encoder *existing = NULL; - - pthread_mutex_lock(&encoders__lock); - /* encoder may not have been added to list yet; check. */ - btf_encoders__for_each_encoder(existing) { - if (encoder == existing) - break; - } - if (encoder == existing) - list_del(&encoder->node); - pthread_mutex_unlock(&encoders__lock); -} - #define PERCPU_SECTION ".data..percpu" /* @@ -868,39 +835,6 @@ static int32_t btf_encoder__add_var_secinfo(struct btf_encoder *encoder, size_t return gobuffer__add(&encoder->secinfo[shndx].secinfo, &si, sizeof(si)); } -int32_t btf_encoder__add_encoder(struct btf_encoder *encoder, struct btf_encoder *other) -{ - size_t shndx; - if (encoder == other) - return 0; - - for (shndx = 1; shndx < other->seccnt; shndx++) { - struct gobuffer *var_secinfo_buf = &other->secinfo[shndx].secinfo; - size_t sz = gobuffer__size(var_secinfo_buf); - uint16_t nr_var_secinfo = sz / sizeof(struct btf_var_secinfo); - uint32_t type_id; - uint32_t next_type_id = btf__type_cnt(encoder->btf); - int32_t i, id; - struct btf_var_secinfo *vsi; - - if (strcmp(encoder->secinfo[shndx].name, other->secinfo[shndx].name)) { - fprintf(stderr, "mismatched ELF sections at index %zu: \"%s\", \"%s\"\n", - shndx, encoder->secinfo[shndx].name, other->secinfo[shndx].name); - return -1; - } - - for (i = 0; i < nr_var_secinfo; i++) { - vsi = (struct btf_var_secinfo *)var_secinfo_buf->entries + i; - type_id = next_type_id + vsi->type - 1; /* Type ID starts from 1 */ - id = btf_encoder__add_var_secinfo(encoder, shndx, type_id, vsi->offset, vsi->size); - if (id < 0) - return id; - } - } - - return btf__add_btf(encoder->btf, other->btf); -} - static int32_t btf_encoder__add_datasec(struct btf_encoder *encoder, size_t shndx) { struct gobuffer *var_secinfo_buf = &encoder->secinfo[shndx].secinfo; @@ -1326,18 +1260,16 @@ static void btf_encoder__delete_saved_funcs(struct btf_encoder *encoder) } } -static int btf_encoder__add_saved_funcs(bool skip_encoding_inconsistent_proto) +static int btf_encoder__add_saved_funcs(struct btf_encoder *encoder, bool skip_encoding_inconsistent_proto) { struct btf_encoder_func_state **saved_fns = NULL, *s; int err = 0, i = 0, j, nr_saved_fns = 0; - struct btf_encoder *e = NULL; - /* Retrieve function states from each encoder, combine them + /* Retrieve function states from the encoder, combine them * and sort by name, addr. */ - btf_encoders__for_each_encoder(e) { - list_for_each_entry(s, &e->func_states, node) - nr_saved_fns++; + list_for_each_entry(s, &encoder->func_states, node) { + nr_saved_fns++; } if (nr_saved_fns == 0) @@ -1349,9 +1281,8 @@ static int btf_encoder__add_saved_funcs(bool skip_encoding_inconsistent_proto) goto out; } - btf_encoders__for_each_encoder(e) { - list_for_each_entry(s, &e->func_states, node) - saved_fns[i++] = s; + list_for_each_entry(s, &encoder->func_states, node) { + saved_fns[i++] = s; } qsort(saved_fns, nr_saved_fns, sizeof(*saved_fns), saved_functions_cmp); @@ -1383,9 +1314,7 @@ static int btf_encoder__add_saved_funcs(bool skip_encoding_inconsistent_proto) out: free(saved_fns); - btf_encoders__for_each_encoder(e) { - btf_encoder__delete_saved_funcs(e); - } + btf_encoder__delete_saved_funcs(encoder); return err; } @@ -2147,7 +2076,7 @@ int btf_encoder__encode(struct btf_encoder *encoder, struct conf_load *conf) int err; size_t shndx; - err = btf_encoder__add_saved_funcs(conf->skip_encoding_btf_inconsistent_proto); + err = btf_encoder__add_saved_funcs(encoder, conf->skip_encoding_btf_inconsistent_proto); if (err < 0) return err; @@ -2553,7 +2482,6 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam if (encoder->verbose) printf("File %s:\n", cu->filename); - btf_encoders__add(encoder); } return encoder; @@ -2570,7 +2498,6 @@ void btf_encoder__delete(struct btf_encoder *encoder) if (encoder == NULL) return; - btf_encoders__delete(encoder); for (shndx = 0; shndx < encoder->seccnt; shndx++) __gobuffer__delete(&encoder->secinfo[shndx].secinfo); free(encoder->secinfo); @@ -2740,8 +2667,3 @@ out: encoder->cu = NULL; return err; } - -struct btf *btf_encoder__btf(struct btf_encoder *encoder) -{ - return encoder->btf; -} diff --git a/btf_encoder.h b/btf_encoder.h index 0081a99..0f345e2 100644 --- a/btf_encoder.h +++ b/btf_encoder.h @@ -27,10 +27,6 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam void btf_encoder__delete(struct btf_encoder *encoder); int btf_encoder__encode(struct btf_encoder *encoder, struct conf_load *conf); - int btf_encoder__encode_cu(struct btf_encoder *encoder, struct cu *cu, struct conf_load *conf_load); -struct btf *btf_encoder__btf(struct btf_encoder *encoder); - -int btf_encoder__add_encoder(struct btf_encoder *encoder, struct btf_encoder *other); #endif /* _BTF_ENCODER_H_ */