From patchwork Tue Oct 10 13:54:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 150805 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2908:b0:403:3b70:6f57 with SMTP id ib8csp217028vqb; Tue, 10 Oct 2023 06:54:54 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGI3gsy/4ahjzfvNZfiyi693b/SERP+RRPJEQKnTZhCKzK5UfPXgeORe7JYiXy6So4+NtHY X-Received: by 2002:a17:903:1210:b0:1c5:9f52:6a5b with SMTP id l16-20020a170903121000b001c59f526a5bmr18730255plh.42.1696946093997; Tue, 10 Oct 2023 06:54:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696946093; cv=none; d=google.com; s=arc-20160816; b=HkGqG1WUGTHQcuxWnW4wC/sFBjDveH3wIoblwTs0Ml3ksF6uHh9IfZjTiSFofp5B74 sKAL2P8WPBLFVaqVOzBHnMTO8RDNTTrUcIKY3pHqXoIcAr2sm8r3oIsSq9VfHoPdF3Ju 436mP5KfeQW35WbgksDM2ILPbmPsH7QR33QA3guJpg7niwElfGRsjQAqF5C6hw39n6qn j2/+/rrLnn0uaiKYArRgcyaihY2/4EENRpRz5UMk7PNuHw0QxarVMA1yhQxxnSBTrzSw y4Z8dm3eTq/uWq5pmjQFVjWtJM6ozVoXsGT8TmHOdqlI4Ovtq0s2oZhCJjAx1/BK8a33 4WXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:message-id:date:subject:cc:to:from:dkim-signature; bh=rxkR3vsxnVBWqrKV7Se05kemCQ3irRdSbrMq8RuAmqk=; fh=/caNsy/NSvy0jHcMMm5HMW3Ql6V7+T60r84HgPaSUkk=; b=rEAEq4YpsLVW4lHSkL2+ACtMEBopyQcUMWTpkoibPD3PTc+Q6BcSq7XtIOtwdjVBv0 29j3a/ByURNVYNcB7JHdmQW0IEzX7DolwA66ZDrejd2Z+nqfQytBHDfDJCenZOITTG1G TDyYaBPi/IDmygdrwdo5ITuZzA6xxCdzJUkmWCmXD7qaMZxa3j/lJ/kfFbuYePV1qn5Y vN9nZBpmphzvOWFBDiB8lffDa7dCDmy6jdxYxGO0FtnMq+atA8dzPkE71QwWKVHNBmfT vRhyGnxo/Pmqq9rfJbpTnTaS2o1YCffQpN4H1MnbS5JnX792SEzLidQSNAnPGaPMXq70 8KDw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WZ9crXHk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from fry.vger.email (fry.vger.email. [2620:137:e000::3:8]) by mx.google.com with ESMTPS id i7-20020a17090332c700b001bc650255b6si12712201plr.390.2023.10.10.06.54.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 06:54:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) client-ip=2620:137:e000::3:8; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WZ9crXHk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id 72D9F80CF513; Tue, 10 Oct 2023 06:54:50 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232289AbjJJNy2 (ORCPT + 20 others); Tue, 10 Oct 2023 09:54:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232047AbjJJNyZ (ORCPT ); Tue, 10 Oct 2023 09:54:25 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 01919B7 for ; Tue, 10 Oct 2023 06:54:23 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B5B53C433C8; Tue, 10 Oct 2023 13:54:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1696946063; bh=CNWvC9NpuHMARHhr8MyzieDE2CJlBdi0q9ScP3wU4Pk=; h=From:To:Cc:Subject:Date:From; b=WZ9crXHkqfRHOuwF5nSBT/H/QN11ggSEKBro2yDSNAM6nbU6+rc79pvijcGFsp4RK kj27z4TB/14zehVxsb1V4yLR8cg9XMwpyG4oDwxPJ42IgHsCU91qO3m01sSWdES8nY M0G03ThhjBrkEjEEQpB2olWoufBDBEC/n4ey4+C/KWh+lF2rAt9IEVzIVG6IrXzuzO NptVfj5tQgvc5lK23RAeiVWx2C4U0u3sxygBOlbffhN1v4kqn9YgENIyjU1Zkq56Ey 9yX1Sc4EmlMNjCd0plo4OFfZ7f7W7Aguu5nJ+RpFjfolPgCUljrueflCbuFCMHDIyl JxT6wHCzBaC6A== From: "Masami Hiramatsu (Google)" To: Martin KaFai Lau , Alexei Starovoitov Cc: linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org Subject: [PATCH] bpf/btf: Move tracing BTF APIs to the BTF library Date: Tue, 10 Oct 2023 22:54:19 +0900 Message-Id: <169694605862.516358.5321950027838863987.stgit@devnote2> X-Mailer: git-send-email 2.34.1 User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=2.4 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, RCVD_IN_SBL_CSS,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Tue, 10 Oct 2023 06:54:50 -0700 (PDT) X-Spam-Level: ** X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1779376947176375262 X-GMAIL-MSGID: 1779376947176375262 From: Masami Hiramatsu (Google) Move the BTF APIs used in tracing to the BTF library code for sharing it with others. Previously, to avoid complex dependency in a series I made it on the tracing tree, but now it is a good time to move it to BPF tree because these functions are pure BTF functions. Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Alan Maguire --- include/linux/btf.h | 24 +++++++++ kernel/bpf/btf.c | 115 +++++++++++++++++++++++++++++++++++++++++ kernel/trace/Makefile | 1 kernel/trace/trace_btf.c | 122 -------------------------------------------- kernel/trace/trace_btf.h | 11 ---- kernel/trace/trace_probe.c | 2 - 6 files changed, 140 insertions(+), 135 deletions(-) delete mode 100644 kernel/trace/trace_btf.c delete mode 100644 kernel/trace/trace_btf.h diff --git a/include/linux/btf.h b/include/linux/btf.h index 928113a80a95..8372d93ea402 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -507,6 +507,14 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, int get_kern_ctx_btf_id(struct bpf_verifier_log *log, enum bpf_prog_type prog_type); bool btf_types_are_same(const struct btf *btf1, u32 id1, const struct btf *btf2, u32 id2); +const struct btf_type *btf_find_func_proto(const char *func_name, + struct btf **btf_p); +const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, + s32 *nr); +const struct btf_member *btf_find_struct_member(struct btf *btf, + const struct btf_type *type, + const char *member_name, + u32 *anon_offset); #else static inline const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id) @@ -559,6 +567,22 @@ static inline bool btf_types_are_same(const struct btf *btf1, u32 id1, { return false; } +static inline const struct btf_type *btf_find_func_proto(const char *func_name, + struct btf **btf_p) +{ + return NULL; +} +static inline const struct btf_param * +btf_get_func_param(const struct btf_type *func_proto, s32 *nr) +{ + return NULL; +} +static inline const struct btf_member * +btf_find_struct_member(struct btf *btf, const struct btf_type *type, + const char *member_name, u32 *anon_offset) +{ + return NULL; +} #endif static inline bool btf_type_is_struct_ptr(struct btf *btf, const struct btf_type *t) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 8090d7fb11ef..e5cbf3b31b78 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -912,6 +912,121 @@ static const struct btf_type *btf_type_skip_qualifiers(const struct btf *btf, return t; } +/* + * Find a function proto type by name, and return the btf_type with its btf + * in *@btf_p. Return NULL if not found. + * Note that caller has to call btf_put(*@btf_p) after using the btf_type. + */ +const struct btf_type *btf_find_func_proto(const char *func_name, struct btf **btf_p) +{ + const struct btf_type *t; + s32 id; + + id = bpf_find_btf_id(func_name, BTF_KIND_FUNC, btf_p); + if (id < 0) + return NULL; + + /* Get BTF_KIND_FUNC type */ + t = btf_type_by_id(*btf_p, id); + if (!t || !btf_type_is_func(t)) + goto err; + + /* The type of BTF_KIND_FUNC is BTF_KIND_FUNC_PROTO */ + t = btf_type_by_id(*btf_p, t->type); + if (!t || !btf_type_is_func_proto(t)) + goto err; + + return t; +err: + btf_put(*btf_p); + return NULL; +} + +/* + * Get function parameter with the number of parameters. + * This can return NULL if the function has no parameters. + * It can return -EINVAL if the @func_proto is not a function proto type. + */ +const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, s32 *nr) +{ + if (!btf_type_is_func_proto(func_proto)) + return ERR_PTR(-EINVAL); + + *nr = btf_type_vlen(func_proto); + if (*nr > 0) + return (const struct btf_param *)(func_proto + 1); + else + return NULL; +} + +#define BTF_ANON_STACK_MAX 16 + +struct btf_anon_stack { + u32 tid; + u32 offset; +}; + +/* + * Find a member of data structure/union by name and return it. + * Return NULL if not found, or -EINVAL if parameter is invalid. + * If the member is an member of anonymous union/structure, the offset + * of that anonymous union/structure is stored into @anon_offset. Caller + * can calculate the correct offset from the root data structure by + * adding anon_offset to the member's offset. + */ +const struct btf_member *btf_find_struct_member(struct btf *btf, + const struct btf_type *type, + const char *member_name, + u32 *anon_offset) +{ + struct btf_anon_stack *anon_stack; + const struct btf_member *member; + u32 tid, cur_offset = 0; + const char *name; + int i, top = 0; + + anon_stack = kcalloc(BTF_ANON_STACK_MAX, sizeof(*anon_stack), GFP_KERNEL); + if (!anon_stack) + return ERR_PTR(-ENOMEM); + +retry: + if (!btf_type_is_struct(type)) { + member = ERR_PTR(-EINVAL); + goto out; + } + + for_each_member(i, type, member) { + if (!member->name_off) { + /* Anonymous union/struct: push it for later use */ + type = btf_type_skip_modifiers(btf, member->type, &tid); + if (type && top < BTF_ANON_STACK_MAX) { + anon_stack[top].tid = tid; + anon_stack[top++].offset = + cur_offset + member->offset; + } + } else { + name = btf_name_by_offset(btf, member->name_off); + if (name && !strcmp(member_name, name)) { + if (anon_offset) + *anon_offset = cur_offset; + goto out; + } + } + } + if (top > 0) { + /* Pop from the anonymous stack and retry */ + tid = anon_stack[--top].tid; + cur_offset = anon_stack[top].offset; + type = btf_type_by_id(btf, tid); + goto retry; + } + member = NULL; + +out: + kfree(anon_stack); + return member; +} + #define BTF_SHOW_MAX_ITER 10 #define BTF_KIND_BIT(kind) (1ULL << kind) diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 057cd975d014..64b61f67a403 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -99,7 +99,6 @@ obj-$(CONFIG_KGDB_KDB) += trace_kdb.o endif obj-$(CONFIG_DYNAMIC_EVENTS) += trace_dynevent.o obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o -obj-$(CONFIG_PROBE_EVENTS_BTF_ARGS) += trace_btf.o obj-$(CONFIG_UPROBE_EVENTS) += trace_uprobe.o obj-$(CONFIG_BOOTTIME_TRACING) += trace_boot.o obj-$(CONFIG_FTRACE_RECORD_RECURSION) += trace_recursion_record.o diff --git a/kernel/trace/trace_btf.c b/kernel/trace/trace_btf.c deleted file mode 100644 index ca224d53bfdc..000000000000 --- a/kernel/trace/trace_btf.c +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include - -#include "trace_btf.h" - -/* - * Find a function proto type by name, and return the btf_type with its btf - * in *@btf_p. Return NULL if not found. - * Note that caller has to call btf_put(*@btf_p) after using the btf_type. - */ -const struct btf_type *btf_find_func_proto(const char *func_name, struct btf **btf_p) -{ - const struct btf_type *t; - s32 id; - - id = bpf_find_btf_id(func_name, BTF_KIND_FUNC, btf_p); - if (id < 0) - return NULL; - - /* Get BTF_KIND_FUNC type */ - t = btf_type_by_id(*btf_p, id); - if (!t || !btf_type_is_func(t)) - goto err; - - /* The type of BTF_KIND_FUNC is BTF_KIND_FUNC_PROTO */ - t = btf_type_by_id(*btf_p, t->type); - if (!t || !btf_type_is_func_proto(t)) - goto err; - - return t; -err: - btf_put(*btf_p); - return NULL; -} - -/* - * Get function parameter with the number of parameters. - * This can return NULL if the function has no parameters. - * It can return -EINVAL if the @func_proto is not a function proto type. - */ -const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, s32 *nr) -{ - if (!btf_type_is_func_proto(func_proto)) - return ERR_PTR(-EINVAL); - - *nr = btf_type_vlen(func_proto); - if (*nr > 0) - return (const struct btf_param *)(func_proto + 1); - else - return NULL; -} - -#define BTF_ANON_STACK_MAX 16 - -struct btf_anon_stack { - u32 tid; - u32 offset; -}; - -/* - * Find a member of data structure/union by name and return it. - * Return NULL if not found, or -EINVAL if parameter is invalid. - * If the member is an member of anonymous union/structure, the offset - * of that anonymous union/structure is stored into @anon_offset. Caller - * can calculate the correct offset from the root data structure by - * adding anon_offset to the member's offset. - */ -const struct btf_member *btf_find_struct_member(struct btf *btf, - const struct btf_type *type, - const char *member_name, - u32 *anon_offset) -{ - struct btf_anon_stack *anon_stack; - const struct btf_member *member; - u32 tid, cur_offset = 0; - const char *name; - int i, top = 0; - - anon_stack = kcalloc(BTF_ANON_STACK_MAX, sizeof(*anon_stack), GFP_KERNEL); - if (!anon_stack) - return ERR_PTR(-ENOMEM); - -retry: - if (!btf_type_is_struct(type)) { - member = ERR_PTR(-EINVAL); - goto out; - } - - for_each_member(i, type, member) { - if (!member->name_off) { - /* Anonymous union/struct: push it for later use */ - type = btf_type_skip_modifiers(btf, member->type, &tid); - if (type && top < BTF_ANON_STACK_MAX) { - anon_stack[top].tid = tid; - anon_stack[top++].offset = - cur_offset + member->offset; - } - } else { - name = btf_name_by_offset(btf, member->name_off); - if (name && !strcmp(member_name, name)) { - if (anon_offset) - *anon_offset = cur_offset; - goto out; - } - } - } - if (top > 0) { - /* Pop from the anonymous stack and retry */ - tid = anon_stack[--top].tid; - cur_offset = anon_stack[top].offset; - type = btf_type_by_id(btf, tid); - goto retry; - } - member = NULL; - -out: - kfree(anon_stack); - return member; -} - diff --git a/kernel/trace/trace_btf.h b/kernel/trace/trace_btf.h deleted file mode 100644 index 4bc44bc261e6..000000000000 --- a/kernel/trace/trace_btf.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include - -const struct btf_type *btf_find_func_proto(const char *func_name, - struct btf **btf_p); -const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, - s32 *nr); -const struct btf_member *btf_find_struct_member(struct btf *btf, - const struct btf_type *type, - const char *member_name, - u32 *anon_offset); diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 4dc74d73fc1d..b33c424b8ee0 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -12,7 +12,7 @@ #define pr_fmt(fmt) "trace_probe: " fmt #include -#include "trace_btf.h" +#include #include "trace_probe.h"