From patchwork Mon Aug 7 02:54:38 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: 131663 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1224654vqr; Sun, 6 Aug 2023 21:42:00 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEhL9CGhIcEQwhpgJi+b04c9LXSIMJ+A7IxbYYuDciqJ3+jwPhuyWV/u8uWvyo5tQs1P660 X-Received: by 2002:a17:903:444:b0:1b8:b29e:b47b with SMTP id iw4-20020a170903044400b001b8b29eb47bmr8152814plb.44.1691383319877; Sun, 06 Aug 2023 21:41:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691383319; cv=none; d=google.com; s=arc-20160816; b=WGqFHLQlHHoxlk1DPokPb1HgI05o4p6AXX+zsHtzuHJ+Oj3Nz3+RPAJ9fO/FKEBUKb UppMeBAX8eMk+roho/3uYA0wdZ2nGzLbax9uNhhdlT574tcSsJsQ1OUIFuilEc3sQf7A UJqz2ceRu2rSArDIBb9pQKQx7fPfBmAyUrwnQkJxYJ+uXDQBVNmLfC8WkLN1YrIiXkzP yzpulqBBvEpKVYViaT/T3yYJYKJaJQcOMqZDk8BauZxzJZeq8zsLwqDC3cYHlHPHAtad 59fy1rlhRUAYWU6B+MfGhXkgU6XuAIXlieNRS+dpKzdvOf/wE1FsAlRNREg9mrpbSyGq ycng== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Jw2E7ijNJ9ZntN9dPdGiL6DywwxC9oEpOI1j3XvbXN4=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=fJHC7qO4Oo0gNnypwBF2pbfiFgUSe840M4cKSQXfDdPSn6PKpPOGLXK3RUIRan6HYK nQA8m8oaosG1ZgEI4B7zdV2ukDWVGLc3EyjYx9Gjl767FF0E/A/VOoDAxL0k6GNa+Qtb L6Q1m+msmdcQLco/MVDu2uIkVGNKXXBqifWmmy90MT0slVTxMNvX8RprwRVuqLaOe2Jk gdldudU2Im3as+WstcTp10pxMIyQrktL70qNeYP6q73vuim/UvSxz67ToGSlmBQBHHx/ m1kDIn8OSrmwY0segoTrssn/m94wB58P3MQXpg8PJ0Di5wuG2pqmiqX4A2TSo5y/rnE/ HRvA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=tg71Pz8P; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u9-20020a17090341c900b001aadba392c1si5452903ple.464.2023.08.06.21.41.47; Sun, 06 Aug 2023 21:41:59 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=tg71Pz8P; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229907AbjHGCy4 (ORCPT + 99 others); Sun, 6 Aug 2023 22:54:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47290 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229919AbjHGCyw (ORCPT ); Sun, 6 Aug 2023 22:54:52 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 127E719A2; Sun, 6 Aug 2023 19:54:44 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7670861147; Mon, 7 Aug 2023 02:54:43 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F0335C433C7; Mon, 7 Aug 2023 02:54:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376882; bh=KReumcvfAA7aUU41c/MWj+LowvbdvMSmvuGEweZl3FI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tg71Pz8PGS+dfk2z61YpIk/EhCz2WG/LCITrji+JxAiJekXPFq+pqvMH/3B+aKPNy vrx5wxFk1zpGIoDoEwyjZ3MOH/HOYy6QKFlrePCfrZj85J/lfG22Y95SDMCBNNDEh3 ZzMoAPJvrsozCqlceg2nup56x9MOFAB20tKAApTkr1kZU998DS7vh+7+fpcEyjq9m5 8iZbSUEetrebIVB9muNVuXja4mEk93MCdvU9t/CCNYDY4ZgDOd0Gy/eEKi75XnXMSB BWU+yjT6LyYyRVIKqiG1oP+nBZCr1kxy5TOzyjmC9N7tUa5eojkFUi5pz9MqHEpiKl F7b/KRCv7mvHQ== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 1/9] tracing/probes: Support BTF argument on module functions Date: Mon, 7 Aug 2023 11:54:38 +0900 Message-Id: <169137687832.271367.4309899034400416156.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773543955796980273 X-GMAIL-MSGID: 1773543955796980273 From: Masami Hiramatsu (Google) Since the btf returned from bpf_get_btf_vmlinux() only covers functions in the vmlinux, BTF argument is not available on the functions in the modules. Use bpf_find_btf_id() instead of bpf_get_btf_vmlinux()+btf_find_name_kind() so that BTF argument can find the correct struct btf and btf_type in it. With this fix, fprobe events can use `$arg*` on module functions as below # grep nf_log_ip_packet /proc/kallsyms ffffffffa0005c00 t nf_log_ip_packet [nf_log_syslog] ffffffffa0005bf0 t __pfx_nf_log_ip_packet [nf_log_syslog] # echo 'f nf_log_ip_packet $arg*' > dynamic_events # cat dynamic_events f:fprobes/nf_log_ip_packet__entry nf_log_ip_packet net=net pf=pf hooknum=hooknum skb=skb in=in out=out loginfo=loginfo prefix=prefix To support the module's btf which is removable, the struct btf needs to be ref-counted. So this also records the btf in the traceprobe_parse_context and returns the refcount when the parse has done. Suggested-by: Alexei Starovoitov Signed-off-by: Masami Hiramatsu (Google) --- Changes in v3: - Newly added. --- include/linux/btf.h | 1 kernel/bpf/btf.c | 2 - kernel/trace/trace_eprobe.c | 4 -- kernel/trace/trace_fprobe.c | 1 kernel/trace/trace_kprobe.c | 1 kernel/trace/trace_probe.c | 100 +++++++++++++++++++++++++------------------ kernel/trace/trace_probe.h | 14 +++++- kernel/trace/trace_uprobe.c | 1 8 files changed, 75 insertions(+), 49 deletions(-) diff --git a/include/linux/btf.h b/include/linux/btf.h index cac9f304e27a..dbfe41a09c4b 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -211,6 +211,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec); bool btf_type_is_void(const struct btf_type *t); s32 btf_find_by_name_kind(const struct btf *btf, const char *name, u8 kind); +s32 bpf_find_btf_id(const char *name, u32 kind, struct btf **btf_p); const struct btf_type *btf_type_skip_modifiers(const struct btf *btf, u32 id, u32 *res_id); const struct btf_type *btf_type_resolve_ptr(const struct btf *btf, diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 817204d53372..b9b0eb1189bb 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -552,7 +552,7 @@ s32 btf_find_by_name_kind(const struct btf *btf, const char *name, u8 kind) return -ENOENT; } -static s32 bpf_find_btf_id(const char *name, u32 kind, struct btf **btf_p) +s32 bpf_find_btf_id(const char *name, u32 kind, struct btf **btf_p) { struct btf *btf; s32 ret; diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c index a0a704ba27db..09bac836d72b 100644 --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -807,13 +807,11 @@ static int trace_eprobe_tp_update_arg(struct trace_eprobe *ep, const char *argv[ int ret; ret = traceprobe_parse_probe_arg(&ep->tp, i, argv[i], &ctx); - if (ret) - return ret; - /* Handle symbols "@" */ if (!ret) ret = traceprobe_update_arg(&ep->tp.args[i]); + traceprobe_finish_parse(&ctx); return ret; } diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index dfe2e546acdc..8f43f1f65b1b 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -1096,6 +1096,7 @@ static int __trace_fprobe_create(int argc, const char *argv[]) } out: + traceprobe_finish_parse(&ctx); trace_probe_log_clear(); kfree(new_argv); kfree(symbol); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 23dba01831f7..cc822f69bfe8 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -907,6 +907,7 @@ static int __trace_kprobe_create(int argc, const char *argv[]) } out: + traceprobe_finish_parse(&ctx); trace_probe_log_clear(); kfree(new_argv); kfree(symbol); diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index c68a72707852..ecbe28f8d676 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -304,16 +304,6 @@ static int parse_trace_event_arg(char *arg, struct fetch_insn *code, #ifdef CONFIG_PROBE_EVENTS_BTF_ARGS -static struct btf *traceprobe_get_btf(void) -{ - struct btf *btf = bpf_get_btf_vmlinux(); - - if (IS_ERR_OR_NULL(btf)) - return NULL; - - return btf; -} - static u32 btf_type_int(const struct btf_type *t) { return *(u32 *)(t + 1); @@ -371,42 +361,49 @@ static const char *type_from_btf_id(struct btf *btf, s32 id) return NULL; } -static const struct btf_type *find_btf_func_proto(const char *funcname) +static const struct btf_type *find_btf_func_proto(const char *funcname, + struct btf **btf_p) { - struct btf *btf = traceprobe_get_btf(); const struct btf_type *t; + struct btf *btf = NULL; s32 id; - if (!btf || !funcname) + if (!funcname) return ERR_PTR(-EINVAL); - id = btf_find_by_name_kind(btf, funcname, BTF_KIND_FUNC); + id = bpf_find_btf_id(funcname, BTF_KIND_FUNC, &btf); if (id <= 0) return ERR_PTR(-ENOENT); /* Get BTF_KIND_FUNC type */ t = btf_type_by_id(btf, id); if (!t || !btf_type_is_func(t)) - return ERR_PTR(-ENOENT); + goto err; /* The type of BTF_KIND_FUNC is BTF_KIND_FUNC_PROTO */ t = btf_type_by_id(btf, t->type); if (!t || !btf_type_is_func_proto(t)) - return ERR_PTR(-ENOENT); + goto err; + *btf_p = btf; return t; + +err: + btf_put(btf); + return ERR_PTR(-ENOENT); } static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr, - bool tracepoint) + struct btf **btf_p, bool tracepoint) { const struct btf_param *param; const struct btf_type *t; + struct btf *btf; if (!funcname || !nr) return ERR_PTR(-EINVAL); - t = find_btf_func_proto(funcname); + t = find_btf_func_proto(funcname, &btf); if (IS_ERR(t)) return (const struct btf_param *)t; @@ -419,29 +416,37 @@ static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr param++; } - if (*nr > 0) + if (*nr > 0) { + *btf_p = btf; return param; - else - return NULL; + } + + btf_put(btf); + return NULL; +} + +static void clear_btf_context(struct traceprobe_parse_context *ctx) +{ + if (ctx->btf) { + btf_put(ctx->btf); + ctx->btf = NULL; + ctx->params = NULL; + ctx->nr_params = 0; + } } static int parse_btf_arg(const char *varname, struct fetch_insn *code, struct traceprobe_parse_context *ctx) { - struct btf *btf = traceprobe_get_btf(); const struct btf_param *params; int i; - if (!btf) { - trace_probe_log_err(ctx->offset, NOSUP_BTFARG); - return -EOPNOTSUPP; - } - if (WARN_ON_ONCE(!ctx->funcname)) return -EINVAL; if (!ctx->params) { - params = find_btf_func_param(ctx->funcname, &ctx->nr_params, + params = find_btf_func_param(ctx->funcname, + &ctx->nr_params, &ctx->btf, ctx->flags & TPARG_FL_TPOINT); if (IS_ERR_OR_NULL(params)) { trace_probe_log_err(ctx->offset, NO_BTF_ENTRY); @@ -452,7 +457,7 @@ static int parse_btf_arg(const char *varname, struct fetch_insn *code, params = ctx->params; for (i = 0; i < ctx->nr_params; i++) { - const char *name = btf_name_by_offset(btf, params[i].name_off); + const char *name = btf_name_by_offset(ctx->btf, params[i].name_off); if (name && !strcmp(name, varname)) { code->op = FETCH_OP_ARG; @@ -470,7 +475,7 @@ static int parse_btf_arg(const char *varname, struct fetch_insn *code, static const struct fetch_type *parse_btf_arg_type(int arg_idx, struct traceprobe_parse_context *ctx) { - struct btf *btf = traceprobe_get_btf(); + struct btf *btf = ctx->btf; const char *typestr = NULL; if (btf && ctx->params) { @@ -485,14 +490,17 @@ static const struct fetch_type *parse_btf_arg_type(int arg_idx, static const struct fetch_type *parse_btf_retval_type( struct traceprobe_parse_context *ctx) { - struct btf *btf = traceprobe_get_btf(); const char *typestr = NULL; const struct btf_type *t; + struct btf *btf; - if (btf && ctx->funcname) { - t = find_btf_func_proto(ctx->funcname); - if (!IS_ERR(t)) + if (ctx->funcname) { + /* Do not use ctx->btf, because it must be used with ctx->param */ + t = find_btf_func_proto(ctx->funcname, &btf); + if (!IS_ERR(t)) { typestr = type_from_btf_id(btf, t->type); + btf_put(btf); + } } return find_fetch_type(typestr, ctx->flags); @@ -501,21 +509,25 @@ static const struct fetch_type *parse_btf_retval_type( static bool is_btf_retval_void(const char *funcname) { const struct btf_type *t; + struct btf *btf; + bool ret; - t = find_btf_func_proto(funcname); + t = find_btf_func_proto(funcname, &btf); if (IS_ERR(t)) return false; - return t->type == 0; + ret = (t->type == 0); + btf_put(btf); + return ret; } #else -static struct btf *traceprobe_get_btf(void) +static void clear_btf_context(struct traceprobe_parse_context *ctx) { - return NULL; + ctx->btf = NULL; } static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr, - bool tracepoint) + struct btf **btf_p, bool tracepoint) { return ERR_PTR(-EOPNOTSUPP); } @@ -1231,7 +1243,6 @@ static int sprint_nth_btf_arg(int idx, const char *type, char *buf, int bufsize, struct traceprobe_parse_context *ctx) { - struct btf *btf = traceprobe_get_btf(); const char *name; int ret; @@ -1239,7 +1250,7 @@ static int sprint_nth_btf_arg(int idx, const char *type, trace_probe_log_err(0, NO_BTFARG); return -ENOENT; } - name = btf_name_by_offset(btf, ctx->params[idx].name_off); + name = btf_name_by_offset(ctx->btf, ctx->params[idx].name_off); if (!name) { trace_probe_log_err(0, NO_BTF_ENTRY); return -ENOENT; @@ -1271,7 +1282,7 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[], return NULL; } - params = find_btf_func_param(ctx->funcname, &nr_params, + params = find_btf_func_param(ctx->funcname, &nr_params, &ctx->btf, ctx->flags & TPARG_FL_TPOINT); if (IS_ERR_OR_NULL(params)) { if (args_idx != -1) { @@ -1337,6 +1348,11 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[], return ERR_PTR(ret); } +void traceprobe_finish_parse(struct traceprobe_parse_context *ctx) +{ + clear_btf_context(ctx); +} + int traceprobe_update_arg(struct probe_arg *arg) { struct fetch_insn *code = arg->code; diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 01ea148723de..4dc91460a75d 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -383,9 +383,11 @@ static inline bool tparg_is_function_entry(unsigned int flags) struct traceprobe_parse_context { struct trace_event_call *event; - const struct btf_param *params; - s32 nr_params; - const char *funcname; + /* BTF related parameters */ + const char *funcname; /* Function name in BTF */ + const struct btf_param *params; /* Parameter of the function */ + s32 nr_params; /* The number of the parameters */ + struct btf *btf; /* The BTF to be used */ unsigned int flags; int offset; }; @@ -400,6 +402,12 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[], extern int traceprobe_update_arg(struct probe_arg *arg); extern void traceprobe_free_probe_arg(struct probe_arg *arg); +/* + * If either traceprobe_parse_probe_arg() or traceprobe_expand_meta_args() is called, + * this MUST be called for clean up the context and return a resource. + */ +void traceprobe_finish_parse(struct traceprobe_parse_context *ctx); + extern int traceprobe_split_symbol_offset(char *symbol, long *offset); int traceprobe_parse_event_name(const char **pevent, const char **pgroup, char *buf, int offset); diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 688bf579f2f1..9790f8f0a32d 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -693,6 +693,7 @@ static int __trace_uprobe_create(int argc, const char **argv) trace_probe_log_set_index(i + 2); ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i], &ctx); + traceprobe_finish_parse(&ctx); if (ret) goto error; } From patchwork Mon Aug 7 02:54:48 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: 131648 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1201036vqr; Sun, 6 Aug 2023 20:18:57 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEVtG+pm57uyzN7wv0xR45LR4+95JIT+V7XzZbBfE44kJk6mOUTlryMzZswuKY1M5BDlSz+ X-Received: by 2002:a05:6358:2795:b0:12f:2573:45b4 with SMTP id l21-20020a056358279500b0012f257345b4mr6909513rwb.26.1691378337179; Sun, 06 Aug 2023 20:18:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691378337; cv=none; d=google.com; s=arc-20160816; b=c8FR4xsm8B3z6NVdDHfqcq7Nj1m3LJ9cvsPwnW29tBWH136cGp+quLXIdq+571f0Z0 20l6NVQ7O/yuJRCBXPWMrjIJlUH93PJxdPanN2hz86ltl6vGxREPAvinqOuOVZCQ7bLQ 9SdQiOmEcG3v4u3x8iYQI0lNCLpDqUejw+yPOGtMKNjOrhqYitd6SuU5+CEECAOQ3Mrq adLg2zNi2b4D+qBfqM2/FFTb6d2Ooa4kvVzAQ09xMhkP0al+pNc5pGllwJKr8Yp7fi0R 4NJYorgXIrl3JzDRS1yOpQoyl0EU+ly07BtnvECrLLVsonVP7fzAFcAwYmzcjT7c8+o4 si7g== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=nGOVxhcGoET+pM75KKkFvEwHRTb6XqdiudlcYorKFJE=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=rMADCS6ANo/G2AmS9tnDoi4JbWANYs9qOqnlrndD5ZWpdUW40OV50mavSo+6ubQVip 1d423Xw9t/X792Jalcun1nW1ZaSVF5aF9dU8qEOXMgR7XJ3KUWBl1UMYZjblWiR36WXM XYU+Vw8QGZAJcpEQBMvK8OgGY2hoKmFNEuyzF7rYbYSx/EjUc9nvx2yfUZruvmfq7UOU IChotQ2EO3zego06r04Fyms6OUF9pS+W+9YQtUW4f47MVZfViNce/o4oDkYLWNwo93XJ 4JnEaGkiG8VR3JLHs0WyJ1T+/AJQfb4KZSCI21qniXNT1KaWNRkdT4JjOMw+srWE/BoH geXw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="R/OlDOAE"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 67-20020a630246000000b0056433b1f347si4911479pgc.801.2023.08.06.20.18.45; Sun, 06 Aug 2023 20:18:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="R/OlDOAE"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229728AbjHGCzM (ORCPT + 99 others); Sun, 6 Aug 2023 22:55:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229736AbjHGCzL (ORCPT ); Sun, 6 Aug 2023 22:55:11 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 529EF1993; Sun, 6 Aug 2023 19:54:54 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6239261147; Mon, 7 Aug 2023 02:54:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C6CBBC433C8; Mon, 7 Aug 2023 02:54:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376892; bh=SRfHcWNQ4ICcFJ2Rv+nVTbK4OPLke1PFMlqHLMr73Mk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R/OlDOAEcrCnXMIXBNskuBSIBOy+SFFnrBSPrRzFcX6lGPAqe+VQG1uFVIZz220QQ I/kRTwHBevcZDOvirmo+Uu70NcDEbcwjcRvDfIYzMWmn0HEa5GuvQ0EBrF9ZwnShzU VEWjMXSf/AKxdsV3P7RXp+CLnSmLvgmNs2Jt1GtLSX5d0EmlZpz1qOO5n2ewc970Qe H2UzMJwOzjvjABWo6ybZdzYzIK0ijzqZNPykJGDS8jtGhH/6icDkQl2uULCGywKHkg Ppl3Vq19jbl63fY01U4UAqlaEkfV5k56Y2nw9aJCbHJCUWwuZFvOkdhs4pNJoy+QTX f498bt3vujqmw== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 2/9] tracing/probes: Move finding func-proto API and getting func-param API to trace_btf Date: Mon, 7 Aug 2023 11:54:48 +0900 Message-Id: <169137688818.271367.11100920774974880710.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773538730991499391 X-GMAIL-MSGID: 1773538730991499391 From: Masami Hiramatsu (Google) Move generic function-proto find API and getting function parameter API to BTF library code from trace_probe.c. This will avoid redundant efforts on different feature. Signed-off-by: Masami Hiramatsu (Google) --- Changes in v3: - Remove perameter check. - Fix a typo. - Add a type check for btf_get_func_param() and add comment for that. - Use bpf_find_btf_id() and add bpf_put(). - Move the code before btf_show() related code. Changes in v5: - Move the generic functions into a new file, trace_btf.c, for avoiding tree-merge conflict. --- kernel/trace/Makefile | 1 + kernel/trace/trace_btf.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace_btf.h | 7 ++++++ kernel/trace/trace_probe.c | 51 +++++++++---------------------------------- 4 files changed, 71 insertions(+), 40 deletions(-) create mode 100644 kernel/trace/trace_btf.c create mode 100644 kernel/trace/trace_btf.h diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 64b61f67a403..057cd975d014 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -99,6 +99,7 @@ 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 new file mode 100644 index 000000000000..82cbbeeda071 --- /dev/null +++ b/kernel/trace/trace_btf.c @@ -0,0 +1,52 @@ +#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; +} + diff --git a/kernel/trace/trace_btf.h b/kernel/trace/trace_btf.h new file mode 100644 index 000000000000..2ef1b2367e1e --- /dev/null +++ b/kernel/trace/trace_btf.h @@ -0,0 +1,7 @@ +// 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); diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index ecbe28f8d676..c3ac5698e80b 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) "trace_probe: " fmt #include +#include "trace_btf.h" #include "trace_probe.h" @@ -361,38 +362,6 @@ static const char *type_from_btf_id(struct btf *btf, s32 id) return NULL; } -static const struct btf_type *find_btf_func_proto(const char *funcname, - struct btf **btf_p) -{ - const struct btf_type *t; - struct btf *btf = NULL; - s32 id; - - if (!funcname) - return ERR_PTR(-EINVAL); - - id = bpf_find_btf_id(funcname, BTF_KIND_FUNC, &btf); - if (id <= 0) - return ERR_PTR(-ENOENT); - - /* Get BTF_KIND_FUNC type */ - t = btf_type_by_id(btf, 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, t->type); - if (!t || !btf_type_is_func_proto(t)) - goto err; - - *btf_p = btf; - return t; - -err: - btf_put(btf); - return ERR_PTR(-ENOENT); -} - static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr, struct btf **btf_p, bool tracepoint) { @@ -403,12 +372,13 @@ static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr if (!funcname || !nr) return ERR_PTR(-EINVAL); - t = find_btf_func_proto(funcname, &btf); - if (IS_ERR(t)) + t = btf_find_func_proto(funcname, &btf); + if (!t) return (const struct btf_param *)t; - *nr = btf_type_vlen(t); - param = (const struct btf_param *)(t + 1); + param = btf_get_func_param(t, nr); + if (IS_ERR_OR_NULL(param)) + goto err; /* Hide the first 'data' argument of tracepoint */ if (tracepoint) { @@ -421,6 +391,7 @@ static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr return param; } +err: btf_put(btf); return NULL; } @@ -496,8 +467,8 @@ static const struct fetch_type *parse_btf_retval_type( if (ctx->funcname) { /* Do not use ctx->btf, because it must be used with ctx->param */ - t = find_btf_func_proto(ctx->funcname, &btf); - if (!IS_ERR(t)) { + t = btf_find_func_proto(ctx->funcname, &btf); + if (t) { typestr = type_from_btf_id(btf, t->type); btf_put(btf); } @@ -512,8 +483,8 @@ static bool is_btf_retval_void(const char *funcname) struct btf *btf; bool ret; - t = find_btf_func_proto(funcname, &btf); - if (IS_ERR(t)) + t = btf_find_func_proto(funcname, &btf); + if (!t) return false; ret = (t->type == 0); From patchwork Mon Aug 7 02:54:58 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: 131655 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1212511vqr; Sun, 6 Aug 2023 21:00:42 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHAlPAZFIE8jelVYOwVDA0ZEuAgNMngi4mCubYAaBQnTf3LkDQVNU6To1M3yHMK8BDy09HG X-Received: by 2002:a17:906:156:b0:99b:5ba6:f2cf with SMTP id 22-20020a170906015600b0099b5ba6f2cfmr6140912ejh.26.1691380841716; Sun, 06 Aug 2023 21:00:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691380841; cv=none; d=google.com; s=arc-20160816; b=U/B8sKkLUO5gYOPewVpbph1O3LSfiqRbRC9VtyQaf0dbSmh+ArlK6rSofNc309xBDo FLAqmCKpjPXMN93hrlBRy35LxuRBPchZIgFUNa1EvrnGeBKOE9dbBYxYDCJTtTkq1bjH CKpkL5fORUv/kVe5erAmS3vgwUsYHftg2F8NStqEjUG3y9MLvjQyltpZ6P2ZX4OYP4zV usgQsoqYn2a8iVHeXfd2i+C7LMy/Y1XPjR0Frzqnm38PSHe8GDGGsZQyLCBRmc5u7hfc zsLwPChETD9BG5iiRYTpQ8yH2s1CLjR6AhvBg0ba0xqk2w4SYXAMVmfGqzD4yGbXyu+4 3ybA== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=z5bD/fowAtp6Bz1Dos+34LmHLP2+agBPEKaP1tHxuX8=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=ze0ySATh+HtE/9nDlX7C2ZfZiVwfudSFFEJ19HmGcBGMblY/1qxxeloKpMFxYwRgM4 2++1F2pYdaz/FX49AbY5wtHEGBKZEB6t9VA7lEqIQnprrcaZIJBgB6XkRvO8XfGG52Sn O/6lSNGTe7nDp2tdzsLlH984LiDu18pBdeTHSbsulOJJwbVwLqQb5OWOQ6IbJOZ4aPf7 RwoJVL0SNFSXyZnIupMGzGRk3pTQ+Jj7IPzdzYTY5u8SzEmqRlqA9N6Syr6JOt5WKXiB 8hZt7hzEaGmccWw+7X46Bd2cRrm1s1mWUwzzZYALCX0PwtKtB3uInEGowEbeBPPUvPY7 lmSQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="qCZG/V3f"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o20-20020a1709061d5400b0099bbc75eb36si4317731ejh.47.2023.08.06.21.00.17; Sun, 06 Aug 2023 21:00:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="qCZG/V3f"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229720AbjHGCzd (ORCPT + 99 others); Sun, 6 Aug 2023 22:55:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229521AbjHGCzc (ORCPT ); Sun, 6 Aug 2023 22:55:32 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88DE81BD2; Sun, 6 Aug 2023 19:55:04 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id CE6FD61337; Mon, 7 Aug 2023 02:55:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3EC5AC433C7; Mon, 7 Aug 2023 02:55:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376903; bh=rV1bOw0hiZEtTOaUVe7fSzFVckAJ245a4sD8LTyT1SE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qCZG/V3fcbZVNuMOaTj3EJJObTyrXo5Q4DaxzsTy7pvcVIHUFsu1FKiF5Hu5cc+MY LcKUM95FijXPv+8p5I+hYNeoi8YsfasDjOC/teENOMP50uosuuXwTq0XH/aMPN6nv2 YkocZgQOhBO706c6uE51VhTbz7YaOXjPiG2tbgYfYmrxrXBkrK9Md+3A3QQc1hRKof wOl1toGSyJ6TDnj44HCBykS5FII3CYI456r7PDovemhXAUzXrDmfvOHEo82M245tcO UVa0qEtZuw0B1Jpl+y2QW6uR/hDz6ZIwBTklAaeU63ciMMDH9+zCVR3ekCOVxjjTSD k3aLJxZAK5uOA== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 3/9] tracing/probes: Add a function to search a member of a struct/union Date: Mon, 7 Aug 2023 11:54:58 +0900 Message-Id: <169137689818.271367.4200174950023036516.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773541357502702657 X-GMAIL-MSGID: 1773541357502702657 From: Masami Hiramatsu (Google) Add btf_find_struct_member() API to search a member of a given data structure or union from the member's name. Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Alan Maguire --- Changes in v3: - Remove simple input check. - Fix unneeded IS_ERR_OR_NULL() check for btf_type_by_id(). - Move the code next to btf_get_func_param(). - Use for_each_member() macro instead of for-loop. - Use btf_type_skip_modifiers() instead of btf_type_by_id(). Changes in v4: - Use a stack for searching in anonymous members instead of nested call. Changes in v5: - Move the generic functions into a new file, trace_btf.c, for avoiding tree-merge conflict. - Return anon_offset for calculating correct offset from root struct. --- kernel/trace/trace_btf.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace_btf.h | 4 +++ 2 files changed, 61 insertions(+) diff --git a/kernel/trace/trace_btf.c b/kernel/trace/trace_btf.c index 82cbbeeda071..109a238437cf 100644 --- a/kernel/trace/trace_btf.c +++ b/kernel/trace/trace_btf.c @@ -50,3 +50,60 @@ const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, s3 return NULL; } +#define BTF_ANON_STACK_MAX 16 + +/* + * 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 { + u32 tid; + u32 offset; + } anon_stack[BTF_ANON_STACK_MAX]; + const struct btf_member *member; + u32 tid, cur_offset = 0; + const char *name; + int i, top = 0; + +retry: + if (!btf_type_is_struct(type)) + return ERR_PTR(-EINVAL); + + 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; + return member; + } + } + } + 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; + } + + return NULL; +} + diff --git a/kernel/trace/trace_btf.h b/kernel/trace/trace_btf.h index 2ef1b2367e1e..fb2919a74225 100644 --- a/kernel/trace/trace_btf.h +++ b/kernel/trace/trace_btf.h @@ -5,3 +5,7 @@ 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); From patchwork Mon Aug 7 02:55:08 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: 131647 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1197261vqr; Sun, 6 Aug 2023 20:07:05 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHmW6AYhiFzVkvLaZjmRlqTkGF8osHYNmXVZXTAA2ADB6F+qyTVY9WksKllDt830tQ93fbK X-Received: by 2002:a19:921a:0:b0:4f8:661f:60a4 with SMTP id u26-20020a19921a000000b004f8661f60a4mr3701939lfd.41.1691377624779; Sun, 06 Aug 2023 20:07:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691377624; cv=none; d=google.com; s=arc-20160816; b=QoGaZqmvknllqFszxD52I2olISvTXEqNATpA8CBkdG1En7IeHIgGUNDiFk5r3hYC1C H+51CA/XU+eOIFaJBlWSvOjyt30UxYi7hK26QXh9FF675JzQgYNnS1+/Xrjq8PU8bBuO Bi2ynyvfnq1avnbAiXq6reEYS4XzX5Uv9LxsMJyP4cDES5XTLknUBxgH6M2ICRGdqe05 MeXrhM/Q9CVpfQIuPUGQtNLNRHZyLyd+O2Ob5SDbjZ6l2WNcsG63UQfYfQnxoQWnob15 VGuFWaii82gJ9Pj5DukQQ5Fs7ffwod1VfFSK76xwz2ZpX++YSPo+ihLMyAq3c5kFHvNY Rapg== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=bAqewmvnA0kirL8YrVgP2I3YKFPUK88ztwqbmIMBV6g=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=XkFNa3X/3OOKvjGfUnuYkMSIHyqurLcYlV8huvviEWh+WM9AAYEAmoKOo1jHrMyK2e ebcghKsrSwEWJ2KnqzxuPZZ6knMRsqwyMsh/+3TTyJfgF9CZE98Ge+Aet6XobPKIJHWb Pd+oYzai3K+rb99esXEqXBf20eqVZXhMuOvV4fQVAtWwQxQqTszSoAk0e9Pf8e0pCWdr POd1a0+WGFCjDZjljaEUtooxaiVtqk//4VImAQ6AIyRiobJAmk7zeiy99Kco2UQQdb0m mSwYOz2Wp8n6USC6bF0gaSV5dNIA9feZiDSntlDa+5L/JVKT9J4AgniMgeWDguYx3zws OPnw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=TlD9iIUB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c9-20020a170906d18900b0099b41fa79f3si4944228ejz.331.2023.08.06.20.06.40; Sun, 06 Aug 2023 20:07:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=TlD9iIUB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229941AbjHGCzt (ORCPT + 99 others); Sun, 6 Aug 2023 22:55:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229554AbjHGCzr (ORCPT ); Sun, 6 Aug 2023 22:55:47 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E2FA1732; Sun, 6 Aug 2023 19:55:14 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id D4DFB61147; Mon, 7 Aug 2023 02:55:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 511F6C433C8; Mon, 7 Aug 2023 02:55:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376913; bh=eF7puk083UBF9yxp0SUFHWsJdaAhex/RA3xisdjFIEA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TlD9iIUByAoroIC8Fz7i7EuEE4iCNVPbFxX0iGnElfVItABlMqe3qu1siXdO2/vM8 U56fdwnsx4Bewe5yQQdns6d3H/R13WtWNGDitximJdwxEgeBBdM0Lp1W0VPZY/Vjon EpcdPFtmbqCmlS2BL+9sh46UJL/1bjO4mwAQpKInTNTDS1/2WhJAy9qfC9vQh18XvI oxezn41SNe7dMByK0ijjNP2SCi3VuCNFMF2/gf5ZVsVNA+XBVB7wc6mC6wUpWi8A1I 9C5yin8LQh6G1aDRTjf4n4y70/+8Bo/F5oAClvS1VnMvvNL1S4uT1dqkf42ZQeLV2q bPeRo4XIY1KDQ== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 4/9] tracing/probes: Support BTF based data structure field access Date: Mon, 7 Aug 2023 11:55:08 +0900 Message-Id: <169137690862.271367.15345269547801333600.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773537984572027169 X-GMAIL-MSGID: 1773537984572027169 From: Masami Hiramatsu (Google) Using BTF to access the fields of a data structure. You can use this for accessing the field with '->' or '.' operation with BTF argument. # echo 't sched_switch next=next->pid vruntime=next->se.vruntime' \ > dynamic_events # echo 1 > events/tracepoints/sched_switch/enable # head -n 40 trace | tail -0 [000] d..3. 272.565382: sched_switch: (__probestub_sched_switch+0x4/0x10) next=26 vruntime=956533179 kcompactd0-26 [000] d..3. 272.565406: sched_switch: (__probestub_sched_switch+0x4/0x10) next=0 vruntime=0 -0 [000] d..3. 273.069441: sched_switch: (__probestub_sched_switch+0x4/0x10) next=9 vruntime=956533179 kworker/0:1-9 [000] d..3. 273.069464: sched_switch: (__probestub_sched_switch+0x4/0x10) next=26 vruntime=956579181 kcompactd0-26 [000] d..3. 273.069480: sched_switch: (__probestub_sched_switch+0x4/0x10) next=0 vruntime=0 -0 [000] d..3. 273.141434: sched_switch: (__probestub_sched_switch+0x4/0x10) next=22 vruntime=956533179 kworker/u2:1-22 [000] d..3. 273.141461: sched_switch: (__probestub_sched_switch+0x4/0x10) next=0 vruntime=0 -0 [000] d..3. 273.480872: sched_switch: (__probestub_sched_switch+0x4/0x10) next=22 vruntime=956585857 kworker/u2:1-22 [000] d..3. 273.480905: sched_switch: (__probestub_sched_switch+0x4/0x10) next=70 vruntime=959533179 sh-70 [000] d..3. 273.481102: sched_switch: (__probestub_sched_switch+0x4/0x10) next=0 vruntime=0 Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Alan Maguire --- Changes in v2: - Use new BTF API for finding the member. Changes in v3: - Update according to previous changes in the series. Changes in v5: - Fix offset for anonymous union/structure members. - Add dot and allow operators in README. --- kernel/trace/trace.c | 3 - kernel/trace/trace_probe.c | 230 +++++++++++++++++++++++++++++++++++++++----- kernel/trace/trace_probe.h | 11 ++ 3 files changed, 216 insertions(+), 28 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index be847d45d81c..5ed90855a3e3 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5716,7 +5716,8 @@ static const char readme_msg[] = "\t fetcharg: (%|$), @
, @[+|-],\n" #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API #ifdef CONFIG_PROBE_EVENTS_BTF_ARGS - "\t $stack, $stack, $retval, $comm, $arg, \n" + "\t $stack, $stack, $retval, $comm, $arg,\n" + "\t [->field[->field|.field...]],\n" #else "\t $stack, $stack, $retval, $comm, $arg,\n" #endif diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index c3ac5698e80b..821f43e5c52b 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -310,16 +310,14 @@ static u32 btf_type_int(const struct btf_type *t) return *(u32 *)(t + 1); } -static const char *type_from_btf_id(struct btf *btf, s32 id) +static const char *fetch_type_from_btf_type(struct btf *btf, + const struct btf_type *type, + struct traceprobe_parse_context *ctx) { - const struct btf_type *t; u32 intdata; - s32 tid; /* TODO: const char * could be converted as a string */ - t = btf_type_skip_modifiers(btf, id, &tid); - - switch (BTF_INFO_KIND(t->info)) { + switch (BTF_INFO_KIND(type->info)) { case BTF_KIND_ENUM: /* enum is "int", so convert to "s32" */ return "s32"; @@ -332,7 +330,7 @@ static const char *type_from_btf_id(struct btf *btf, s32 id) else return "x32"; case BTF_KIND_INT: - intdata = btf_type_int(t); + intdata = btf_type_int(type); if (BTF_INT_ENCODING(intdata) & BTF_INT_SIGNED) { switch (BTF_INT_BITS(intdata)) { case 8: @@ -355,6 +353,10 @@ static const char *type_from_btf_id(struct btf *btf, s32 id) case 64: return "u64"; } + /* bitfield, size is encoded in the type */ + ctx->last_bitsize = BTF_INT_BITS(intdata); + ctx->last_bitoffs += BTF_INT_OFFSET(intdata); + return "u64"; } } /* TODO: support other types */ @@ -406,15 +408,136 @@ static void clear_btf_context(struct traceprobe_parse_context *ctx) } } -static int parse_btf_arg(const char *varname, struct fetch_insn *code, +/* Return 1 if the field separater is arrow operator ('->') */ +static int split_next_field(char *varname, char **next_field, + struct traceprobe_parse_context *ctx) +{ + char *field; + int ret = 0; + + field = strpbrk(varname, ".-"); + if (field) { + if (field[0] == '-' && field[1] == '>') { + field[0] = '\0'; + field += 2; + ret = 1; + } else if (field[0] == '.') { + field[0] = '\0'; + field += 1; + } else { + trace_probe_log_err(ctx->offset + field - varname, BAD_HYPHEN); + return -EINVAL; + } + *next_field = field; + } + + return ret; +} + +/* + * Parse the field of data structure. The @type must be a pointer type + * pointing the target data structure type. + */ +static int parse_btf_field(char *fieldname, const struct btf_type *type, + struct fetch_insn **pcode, struct fetch_insn *end, + struct traceprobe_parse_context *ctx) +{ + struct fetch_insn *code = *pcode; + const struct btf_member *field; + u32 bitoffs, anon_offs; + char *next; + int is_ptr; + s32 tid; + + do { + /* Outer loop for solving arrow operator ('->') */ + if (BTF_INFO_KIND(type->info) != BTF_KIND_PTR) { + trace_probe_log_err(ctx->offset, NO_PTR_STRCT); + return -EINVAL; + } + /* Convert a struct pointer type to a struct type */ + type = btf_type_skip_modifiers(ctx->btf, type->type, &tid); + if (!type) { + trace_probe_log_err(ctx->offset, BAD_BTF_TID); + return -EINVAL; + } + + bitoffs = 0; + do { + /* Inner loop for solving dot operator ('.') */ + next = NULL; + is_ptr = split_next_field(fieldname, &next, ctx); + if (is_ptr < 0) + return is_ptr; + + anon_offs = 0; + field = btf_find_struct_member(ctx->btf, type, fieldname, + &anon_offs); + if (!field) { + trace_probe_log_err(ctx->offset, NO_BTF_FIELD); + return -ENOENT; + } + /* Add anonymous structure/union offset */ + bitoffs += anon_offs; + + /* Accumulate the bit-offsets of the dot-connected fields */ + if (btf_type_kflag(type)) { + bitoffs += BTF_MEMBER_BIT_OFFSET(field->offset); + ctx->last_bitsize = BTF_MEMBER_BITFIELD_SIZE(field->offset); + } else { + bitoffs += field->offset; + ctx->last_bitsize = 0; + } + + type = btf_type_skip_modifiers(ctx->btf, field->type, &tid); + if (!type) { + trace_probe_log_err(ctx->offset, BAD_BTF_TID); + return -EINVAL; + } + + ctx->offset += next - fieldname; + fieldname = next; + } while (!is_ptr && fieldname); + + if (++code == end) { + trace_probe_log_err(ctx->offset, TOO_MANY_OPS); + return -EINVAL; + } + code->op = FETCH_OP_DEREF; /* TODO: user deref support */ + code->offset = bitoffs / 8; + *pcode = code; + + ctx->last_bitoffs = bitoffs % 8; + ctx->last_type = type; + } while (fieldname); + + return 0; +} + +static int parse_btf_arg(char *varname, + struct fetch_insn **pcode, struct fetch_insn *end, struct traceprobe_parse_context *ctx) { + struct fetch_insn *code = *pcode; const struct btf_param *params; - int i; + const struct btf_type *type; + char *field = NULL; + int i, is_ptr; + u32 tid; if (WARN_ON_ONCE(!ctx->funcname)) return -EINVAL; + is_ptr = split_next_field(varname, &field, ctx); + if (is_ptr < 0) + return is_ptr; + if (!is_ptr && field) { + /* dot-connected field on an argument is not supported. */ + trace_probe_log_err(ctx->offset + field - varname, + NOSUP_DAT_ARG); + return -EOPNOTSUPP; + } + if (!ctx->params) { params = find_btf_func_param(ctx->funcname, &ctx->nr_params, &ctx->btf, @@ -436,24 +559,39 @@ static int parse_btf_arg(const char *varname, struct fetch_insn *code, code->param = i + 1; else code->param = i; - return 0; + + tid = params[i].type; + goto found; } } trace_probe_log_err(ctx->offset, NO_BTFARG); return -ENOENT; + +found: + type = btf_type_skip_modifiers(ctx->btf, tid, &tid); + if (!type) { + trace_probe_log_err(ctx->offset, BAD_BTF_TID); + return -EINVAL; + } + /* Initialize the last type information */ + ctx->last_type = type; + ctx->last_bitoffs = 0; + ctx->last_bitsize = 0; + if (field) { + ctx->offset += field - varname; + return parse_btf_field(field, type, pcode, end, ctx); + } + return 0; } -static const struct fetch_type *parse_btf_arg_type(int arg_idx, +static const struct fetch_type *parse_btf_arg_type( struct traceprobe_parse_context *ctx) { struct btf *btf = ctx->btf; const char *typestr = NULL; - if (btf && ctx->params) { - if (ctx->flags & TPARG_FL_TPOINT) - arg_idx--; - typestr = type_from_btf_id(btf, ctx->params[arg_idx].type); - } + if (btf && ctx->last_type) + typestr = fetch_type_from_btf_type(btf, ctx->last_type, ctx); return find_fetch_type(typestr, ctx->flags); } @@ -462,14 +600,16 @@ static const struct fetch_type *parse_btf_retval_type( struct traceprobe_parse_context *ctx) { const char *typestr = NULL; - const struct btf_type *t; + const struct btf_type *type; struct btf *btf; if (ctx->funcname) { /* Do not use ctx->btf, because it must be used with ctx->param */ - t = btf_find_func_proto(ctx->funcname, &btf); - if (t) { - typestr = type_from_btf_id(btf, t->type); + type = btf_find_func_proto(ctx->funcname, &btf); + if (type) { + type = btf_type_skip_modifiers(btf, type->type, NULL); + if (!IS_ERR_OR_NULL(type)) + typestr = fetch_type_from_btf_type(btf, type, ctx); btf_put(btf); } } @@ -477,6 +617,28 @@ static const struct fetch_type *parse_btf_retval_type( return find_fetch_type(typestr, ctx->flags); } +static int parse_btf_bitfield(struct fetch_insn **pcode, + struct traceprobe_parse_context *ctx) +{ + struct fetch_insn *code = *pcode; + + if ((ctx->last_bitsize % 8 == 0) && ctx->last_bitoffs == 0) + return 0; + + code++; + if (code->op != FETCH_OP_NOP) { + trace_probe_log_err(ctx->offset, TOO_MANY_OPS); + return -EINVAL; + } + *pcode = code; + + code->op = FETCH_OP_MOD_BF; + code->lshift = 64 - (ctx->last_bitsize + ctx->last_bitoffs); + code->rshift = 64 - ctx->last_bitsize; + code->basesize = 64 / 8; + return 0; +} + static bool is_btf_retval_void(const char *funcname) { const struct btf_type *t; @@ -503,14 +665,22 @@ static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr return ERR_PTR(-EOPNOTSUPP); } -static int parse_btf_arg(const char *varname, struct fetch_insn *code, +static int parse_btf_arg(char *varname, + struct fetch_insn **pcode, struct fetch_insn *end, struct traceprobe_parse_context *ctx) { trace_probe_log_err(ctx->offset, NOSUP_BTFARG); return -EOPNOTSUPP; } -#define parse_btf_arg_type(idx, ctx) \ +static int parse_btf_bitfield(struct fetch_insn **pcode, + struct traceprobe_parse_context *ctx) +{ + trace_probe_log_err(ctx->offset, NOSUP_BTFARG); + return -EOPNOTSUPP; +} + +#define parse_btf_arg_type(ctx) \ find_fetch_type(NULL, ctx->flags) #define parse_btf_retval_type(ctx) \ @@ -778,6 +948,8 @@ parse_probe_arg(char *arg, const struct fetch_type *type, code->op = deref; code->offset = offset; + /* Reset the last type if used */ + ctx->last_type = NULL; } break; case '\\': /* Immediate value */ @@ -801,7 +973,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type, trace_probe_log_err(ctx->offset, NOSUP_BTFARG); return -EINVAL; } - ret = parse_btf_arg(arg, code, ctx); + ret = parse_btf_arg(arg, pcode, end, ctx); break; } } @@ -947,6 +1119,7 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, goto out; code[FETCH_INSN_MAX - 1].op = FETCH_OP_END; + ctx->last_type = NULL; ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1], ctx); if (ret) @@ -954,9 +1127,9 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, /* Update storing type if BTF is available */ if (IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS) && !t) { - if (code->op == FETCH_OP_ARG) - parg->type = parse_btf_arg_type(code->param, ctx); - else if (code->op == FETCH_OP_RETVAL) + if (ctx->last_type) + parg->type = parse_btf_arg_type(ctx); + else if (ctx->flags & TPARG_FL_RETURN) parg->type = parse_btf_retval_type(ctx); } @@ -1031,6 +1204,11 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, trace_probe_log_err(ctx->offset + t - arg, BAD_BITFIELD); goto fail; } + } else if (IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS) && + ctx->last_type) { + ret = parse_btf_bitfield(&code, ctx); + if (ret) + goto fail; } ret = -EINVAL; /* Loop(Array) operation */ diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 4dc91460a75d..6111f1ffca6c 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -388,6 +388,9 @@ struct traceprobe_parse_context { const struct btf_param *params; /* Parameter of the function */ s32 nr_params; /* The number of the parameters */ struct btf *btf; /* The BTF to be used */ + const struct btf_type *last_type; /* Saved type */ + u32 last_bitoffs; /* Saved bitoffs */ + u32 last_bitsize; /* Saved bitsize */ unsigned int flags; int offset; }; @@ -503,7 +506,13 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, C(BAD_VAR_ARGS, "$arg* must be an independent parameter without name etc."),\ C(NOFENTRY_ARGS, "$arg* can be used only on function entry"), \ C(DOUBLE_ARGS, "$arg* can be used only once in the parameters"), \ - C(ARGS_2LONG, "$arg* failed because the argument list is too long"), + C(ARGS_2LONG, "$arg* failed because the argument list is too long"), \ + C(ARGIDX_2BIG, "$argN index is too big"), \ + C(NO_PTR_STRCT, "This is not a pointer to union/structure."), \ + C(NOSUP_DAT_ARG, "Non pointer structure/union argument is not supported."),\ + C(BAD_HYPHEN, "Failed to parse single hyphen. Forgot '>'?"), \ + C(NO_BTF_FIELD, "This field is not found."), \ + C(BAD_BTF_TID, "Failed to get BTF type info."), #undef C #define C(a, b) TP_ERR_##a From patchwork Mon Aug 7 02:55:18 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: 131656 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1212867vqr; Sun, 6 Aug 2023 21:01:36 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGlancofHX1yrC6tL3zY0CIvreglpU82u12X8Z2p+DuBwzZLRDkwI3rADcUsNBvqs3C5uNN X-Received: by 2002:a05:6a20:6a0f:b0:12e:44:a1a6 with SMTP id p15-20020a056a206a0f00b0012e0044a1a6mr6768180pzk.11.1691380895932; Sun, 06 Aug 2023 21:01:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691380895; cv=none; d=google.com; s=arc-20160816; b=vetM+DSaVAKRsFLQXrv76qCrX+DnuBZ4osc1po3fjb+E8dt/DUJYAK6epANxzAiN3+ 07yRaDp1OFHWTiPm+2axk6q/E2cpxfPbySrvmMtxzymzyR5ywxTwYWZhP0iOGlylWup3 wYREZy5nkXk8jMA9w4+PJ2Ab+77QcYeyTVotn9UnwT6hVrkQ61ck0AcD0plJu+g85ZTD 3l2+uB6xqcz5n0BwRmbsrPffj5uyBuVwz+XwEQyJVSweQqlsHEpv/koy2wi9AdCcSWd6 X1dVE9q6SIwcBX1XYVV7CUnKE5L3sF1E7lz+Tmh0gnfMh10kGTvMQCFeA46pnIUah8FK 3vAw== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=8v3UetG079ewF1fiytjSHjtkaQ2Rb2oKH34pOzbhgcI=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=tXKTLLpF92YAVVt8qknVsIuperV7nFEK9zcTzwb0RKumLxT0ObZdk/PQjUKO5qNEfl C0MLHK5b/t7pVjQCPEcHi/vH6c8Oh48Y1PXvxjXJYiQj6JwDu/eCyYkzKowJw6VhtSUN nXNY14OELIrzh8jphslqSxMsZwmDyEdnS5nUWVZdRTL8PPRSrh83L3eFzviW9Cu9ND+q W5kmstysX5gXzrVD1BU5u2uoiesLXQ3AjcLT1RZMk/Hi65KytL+vDwhFl7426FG3HdjZ ScfnNoz2hfcbd1TmM3PRpxyyiTs5gvU52ndAitwUbTwx1LwTn/rYEYOaHCuAnxVVN5O6 cTVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ih0krtd4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q15-20020a63e94f000000b00543a6ce8c33si5133574pgj.78.2023.08.06.21.01.23; Sun, 06 Aug 2023 21:01:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ih0krtd4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229644AbjHGC4A (ORCPT + 99 others); Sun, 6 Aug 2023 22:56:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48542 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229853AbjHGCz6 (ORCPT ); Sun, 6 Aug 2023 22:55:58 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BC0A919BC; Sun, 6 Aug 2023 19:55:27 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id CEE2E61347; Mon, 7 Aug 2023 02:55:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 37FBBC433C7; Mon, 7 Aug 2023 02:55:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376923; bh=oGPU2qozXtuEf14iocpSzniQ83hSVXHfLyfBmI0OE2A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ih0krtd4eAsAeggMCajLm9mLbVSl0IYn1TbR+YCDNaNziq7ZB+tiNA4GajJUvnkYA I84YsQ9fG+/Pu8CYmkhcI1wbrexZww6Nxw0sV4rmwVoIA2wdGO4My9FtiVX199Jz8c 5hZS5FWr8GdKwCXHgosnhLqq6xaD4v9Wng0Xzj0vOPFgJZeXv881VUojhhrdtQbMWQ c6CeGPbaU+0XeUv20F0CtqgDaAkBQhfLjSAvKqdLlQOjDbC9eu4h9jQpy/CWHw2rNt mXPpNj+3Y2QLfeosuo9+Exrb14Qmt/+xac+BJbYptbNHmGrhHqeFQcarR0dBgFfl3G 3PUNdGlHQA34Q== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 5/9] tracing/probes: Support BTF field access from $retval Date: Mon, 7 Aug 2023 11:55:18 +0900 Message-Id: <169137691866.271367.17475776112000287816.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773541414442616165 X-GMAIL-MSGID: 1773541414442616165 From: Masami Hiramatsu (Google) Support BTF argument on '$retval' for function return events including kretprobe and fprobe for accessing the return value. This also allows user to access its fields if the return value is a pointer of a data structure. E.g. # echo 'f getname_flags%return +0($retval->name):string' \ > dynamic_events # echo 1 > events/fprobes/getname_flags__exit/enable # ls > /dev/null # head -n 40 trace | tail ls-87 [000] ...1. 8067.616101: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./function_profile_enabled" ls-87 [000] ...1. 8067.616108: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./trace_stat" ls-87 [000] ...1. 8067.616115: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./set_graph_notrace" ls-87 [000] ...1. 8067.616122: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./set_graph_function" ls-87 [000] ...1. 8067.616129: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./set_ftrace_notrace" ls-87 [000] ...1. 8067.616135: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./set_ftrace_filter" ls-87 [000] ...1. 8067.616143: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./touched_functions" ls-87 [000] ...1. 8067.616237: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./enabled_functions" ls-87 [000] ...1. 8067.616245: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./available_filter_functions" ls-87 [000] ...1. 8067.616253: getname_flags__exit: (vfs_fstatat+0x3c/0x70 <- getname_flags) arg1="./set_ftrace_notrace_pid" Signed-off-by: Masami Hiramatsu (Google) --- Changes in v2: - Use '$retval' instead of 'retval' because it is confusing. Changes in v3: - Introduce query_btf_context() to cache the btf related data (function prototype) for using common field analyzing code with function parameters. Changes in v3.1: - Return int error code from query_btf_context() if !CONFIG_PROBE_EVENTS_BTF_ARGS Changes in v4: - Fix wrong BTF access if query_btf_context() is failed in parse_btf_arg(). - Return error if $retval accesses a field but BTF is not found. --- kernel/trace/trace_probe.c | 187 ++++++++++++++++++++------------------------ kernel/trace/trace_probe.h | 1 2 files changed, 86 insertions(+), 102 deletions(-) diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 821f43e5c52b..7345e1af4db2 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -364,38 +364,46 @@ static const char *fetch_type_from_btf_type(struct btf *btf, return NULL; } -static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr, - struct btf **btf_p, bool tracepoint) +static int query_btf_context(struct traceprobe_parse_context *ctx) { const struct btf_param *param; - const struct btf_type *t; + const struct btf_type *type; struct btf *btf; + s32 nr; - if (!funcname || !nr) - return ERR_PTR(-EINVAL); + if (ctx->btf) + return 0; - t = btf_find_func_proto(funcname, &btf); - if (!t) - return (const struct btf_param *)t; + if (!ctx->funcname) + return -EINVAL; - param = btf_get_func_param(t, nr); - if (IS_ERR_OR_NULL(param)) - goto err; + type = btf_find_func_proto(ctx->funcname, &btf); + if (!type) + return -ENOENT; - /* Hide the first 'data' argument of tracepoint */ - if (tracepoint) { - (*nr)--; - param++; + ctx->btf = btf; + ctx->proto = type; + + /* ctx->params is optional, since func(void) will not have params. */ + nr = 0; + param = btf_get_func_param(type, &nr); + if (!IS_ERR_OR_NULL(param)) { + /* Hide the first 'data' argument of tracepoint */ + if (ctx->flags & TPARG_FL_TPOINT) { + nr--; + param++; + } } - if (*nr > 0) { - *btf_p = btf; - return param; + if (nr > 0) { + ctx->nr_params = nr; + ctx->params = param; + } else { + ctx->nr_params = 0; + ctx->params = NULL; } -err: - btf_put(btf); - return NULL; + return 0; } static void clear_btf_context(struct traceprobe_parse_context *ctx) @@ -403,6 +411,7 @@ static void clear_btf_context(struct traceprobe_parse_context *ctx) if (ctx->btf) { btf_put(ctx->btf); ctx->btf = NULL; + ctx->proto = NULL; ctx->params = NULL; ctx->nr_params = 0; } @@ -522,7 +531,7 @@ static int parse_btf_arg(char *varname, const struct btf_param *params; const struct btf_type *type; char *field = NULL; - int i, is_ptr; + int i, is_ptr, ret; u32 tid; if (WARN_ON_ONCE(!ctx->funcname)) @@ -538,17 +547,37 @@ static int parse_btf_arg(char *varname, return -EOPNOTSUPP; } - if (!ctx->params) { - params = find_btf_func_param(ctx->funcname, - &ctx->nr_params, &ctx->btf, - ctx->flags & TPARG_FL_TPOINT); - if (IS_ERR_OR_NULL(params)) { + if (ctx->flags & TPARG_FL_RETURN) { + if (strcmp(varname, "$retval") != 0) { + trace_probe_log_err(ctx->offset, NO_BTFARG); + return -ENOENT; + } + code->op = FETCH_OP_RETVAL; + /* Check whether the function return type is not void */ + if (query_btf_context(ctx) == 0) { + if (ctx->proto->type == 0) { + trace_probe_log_err(ctx->offset, NO_RETVAL); + return -ENOENT; + } + tid = ctx->proto->type; + goto found; + } + if (field) { + trace_probe_log_err(ctx->offset + field - varname, + NO_BTF_ENTRY); + return -ENOENT; + } + return 0; + } + + if (!ctx->btf) { + ret = query_btf_context(ctx); + if (ret < 0 || ctx->nr_params == 0) { trace_probe_log_err(ctx->offset, NO_BTF_ENTRY); return PTR_ERR(params); } - ctx->params = params; - } else - params = ctx->params; + } + params = ctx->params; for (i = 0; i < ctx->nr_params; i++) { const char *name = btf_name_by_offset(ctx->btf, params[i].name_off); @@ -559,7 +588,6 @@ static int parse_btf_arg(char *varname, code->param = i + 1; else code->param = i; - tid = params[i].type; goto found; } @@ -584,7 +612,7 @@ static int parse_btf_arg(char *varname, return 0; } -static const struct fetch_type *parse_btf_arg_type( +static const struct fetch_type *find_fetch_type_from_btf_type( struct traceprobe_parse_context *ctx) { struct btf *btf = ctx->btf; @@ -596,27 +624,6 @@ static const struct fetch_type *parse_btf_arg_type( return find_fetch_type(typestr, ctx->flags); } -static const struct fetch_type *parse_btf_retval_type( - struct traceprobe_parse_context *ctx) -{ - const char *typestr = NULL; - const struct btf_type *type; - struct btf *btf; - - if (ctx->funcname) { - /* Do not use ctx->btf, because it must be used with ctx->param */ - type = btf_find_func_proto(ctx->funcname, &btf); - if (type) { - type = btf_type_skip_modifiers(btf, type->type, NULL); - if (!IS_ERR_OR_NULL(type)) - typestr = fetch_type_from_btf_type(btf, type, ctx); - btf_put(btf); - } - } - - return find_fetch_type(typestr, ctx->flags); -} - static int parse_btf_bitfield(struct fetch_insn **pcode, struct traceprobe_parse_context *ctx) { @@ -639,30 +646,15 @@ static int parse_btf_bitfield(struct fetch_insn **pcode, return 0; } -static bool is_btf_retval_void(const char *funcname) -{ - const struct btf_type *t; - struct btf *btf; - bool ret; - - t = btf_find_func_proto(funcname, &btf); - if (!t) - return false; - - ret = (t->type == 0); - btf_put(btf); - return ret; -} #else static void clear_btf_context(struct traceprobe_parse_context *ctx) { ctx->btf = NULL; } -static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr, - struct btf **btf_p, bool tracepoint) +static int query_btf_context(struct traceprobe_parse_context *ctx) { - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; } static int parse_btf_arg(char *varname, @@ -680,24 +672,23 @@ static int parse_btf_bitfield(struct fetch_insn **pcode, return -EOPNOTSUPP; } -#define parse_btf_arg_type(ctx) \ - find_fetch_type(NULL, ctx->flags) - -#define parse_btf_retval_type(ctx) \ +#define find_fetch_type_from_btf_type(ctx) \ find_fetch_type(NULL, ctx->flags) -#define is_btf_retval_void(funcname) (false) - #endif #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) -static int parse_probe_vars(char *arg, const struct fetch_type *t, - struct fetch_insn *code, +/* Parse $vars. @orig_arg points '$', which syncs to @ctx->offset */ +static int parse_probe_vars(char *orig_arg, const struct fetch_type *t, + struct fetch_insn **pcode, + struct fetch_insn *end, struct traceprobe_parse_context *ctx) { - unsigned long param; + struct fetch_insn *code = *pcode; int err = TP_ERR_BAD_VAR; + char *arg = orig_arg + 1; + unsigned long param; int ret = 0; int len; @@ -716,18 +707,17 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, goto inval; } - if (strcmp(arg, "retval") == 0) { - if (ctx->flags & TPARG_FL_RETURN) { - if ((ctx->flags & TPARG_FL_KERNEL) && - is_btf_retval_void(ctx->funcname)) { - err = TP_ERR_NO_RETVAL; - goto inval; - } + if (str_has_prefix(arg, "retval")) { + if (!(ctx->flags & TPARG_FL_RETURN)) { + err = TP_ERR_RETVAL_ON_PROBE; + goto inval; + } + if (!(ctx->flags & TPARG_FL_KERNEL) || + !IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS)) { code->op = FETCH_OP_RETVAL; return 0; } - err = TP_ERR_RETVAL_ON_PROBE; - goto inval; + return parse_btf_arg(orig_arg, pcode, end, ctx); } len = str_has_prefix(arg, "stack"); @@ -829,7 +819,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type, switch (arg[0]) { case '$': - ret = parse_probe_vars(arg + 1, type, code, ctx); + ret = parse_probe_vars(arg, type, pcode, end, ctx); break; case '%': /* named register */ @@ -1126,12 +1116,9 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, goto fail; /* Update storing type if BTF is available */ - if (IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS) && !t) { - if (ctx->last_type) - parg->type = parse_btf_arg_type(ctx); - else if (ctx->flags & TPARG_FL_RETURN) - parg->type = parse_btf_retval_type(ctx); - } + if (IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS) && + !t && ctx->last_type) + parg->type = find_fetch_type_from_btf_type(ctx); ret = -EINVAL; /* Store operation */ @@ -1420,7 +1407,6 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[], const struct btf_param *params = NULL; int i, j, n, used, ret, args_idx = -1; const char **new_argv = NULL; - int nr_params; ret = argv_has_var_arg(argc, argv, &args_idx, ctx); if (ret < 0) @@ -1431,9 +1417,8 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[], return NULL; } - params = find_btf_func_param(ctx->funcname, &nr_params, &ctx->btf, - ctx->flags & TPARG_FL_TPOINT); - if (IS_ERR_OR_NULL(params)) { + ret = query_btf_context(ctx); + if (ret < 0 || ctx->nr_params == 0) { if (args_idx != -1) { /* $arg* requires BTF info */ trace_probe_log_err(0, NOSUP_BTFARG); @@ -1442,8 +1427,6 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[], *new_argc = argc; return NULL; } - ctx->params = params; - ctx->nr_params = nr_params; if (args_idx >= 0) *new_argc = argc + ctx->nr_params - 1; @@ -1458,7 +1441,7 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[], for (i = 0, j = 0; i < argc; i++) { trace_probe_log_set_index(i + 2); if (i == args_idx) { - for (n = 0; n < nr_params; n++) { + for (n = 0; n < ctx->nr_params; n++) { ret = sprint_nth_btf_arg(n, "", buf + used, bufsize - used, ctx); if (ret < 0) diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 6111f1ffca6c..9184c84833f8 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -385,6 +385,7 @@ struct traceprobe_parse_context { struct trace_event_call *event; /* BTF related parameters */ const char *funcname; /* Function name in BTF */ + const struct btf_type *proto; /* Prototype of the function */ const struct btf_param *params; /* Parameter of the function */ s32 nr_params; /* The number of the parameters */ struct btf *btf; /* The BTF to be used */ From patchwork Mon Aug 7 02:55:28 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: 131649 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1201121vqr; Sun, 6 Aug 2023 20:19:11 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEtDqcb7ihgkblXKuM/ADBqDqx8G+ZCtrTolqRoPFjb+aVZWum3Dm07u8YYTcboGiJnIBcY X-Received: by 2002:a17:902:dad1:b0:1b8:6987:de84 with SMTP id q17-20020a170902dad100b001b86987de84mr11029657plx.48.1691378351275; Sun, 06 Aug 2023 20:19:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691378351; cv=none; d=google.com; s=arc-20160816; b=AA52vS7gZ+vtDyqTBi7CZcX51SvSTToFLJ93txAsynFPDNeb3IPk9ejDeI37oW2H0A sXujV2Zqm+1VFtQT8kt9bmvrboYvKE+OhrfLFoquewVFGsd2AVmMGqYCFjDTyVAE5AeR p0or1S2H880OitUcSSvZ0ZgJpQmiD7nPHEel522QhBXq/w6eZnNjUhbRgSIDgFho22SP GGz+kWA4XG76GDTKnf84UFqdEnB0QT4At672CqS5jeedrB+NklJnFY4NJFOrTB6OESPd aoXDoVKBw9ucqtHZPCH5JUGIe2JnaKPbhuS+1qknVnt0peuJOpvVjkpEBNBGWDyiXFj1 a/dg== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=v1rkQobvWMC3LMduQqF0iNYSiodbDgW2OuKH645ulTg=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=aqD/8VoMUY69i6cb2ef4IsoBSKy0/YLQ/Sm9/AKzs5buVhtLp398+b9y2kjJFEtrCl sHfcOPZDYTXpgK41vaZAlCY0ezcAm4Yho61OsBvAtmntN8kodaq4yeFtbKy5nad2piiS 0c08IkgGlyP648aKLc40NLBWcfSI5NqM1N/wwljdWa8HGPQUKlFRTpqyM3TESYR8WyBy GVaw7v/RISCovUxS/k0Jt8PTXm7sPeIHK0NVDOV9345esmelZBnhfAMnkgFIFqJSHWXK rKZ21Lo5l4StgN+yywOpULguy399XmJfA/jpl2cDVCP4RAlH8VkzDtPGpSjbj8X32nBu U80g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=TLg6CDNp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u16-20020a170902e81000b001b8805f98e9si5218901plg.452.2023.08.06.20.18.58; Sun, 06 Aug 2023 20:19:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=TLg6CDNp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229938AbjHGC4K (ORCPT + 99 others); Sun, 6 Aug 2023 22:56:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48736 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229853AbjHGC4G (ORCPT ); Sun, 6 Aug 2023 22:56:06 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42B2A1BD4; Sun, 6 Aug 2023 19:55:34 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id BEAED6133F; Mon, 7 Aug 2023 02:55:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 58C84C433CC; Mon, 7 Aug 2023 02:55:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376933; bh=nbJctgHoWt1eNQqxV3NpXqVI8hkS5eFFrSto2wUxsec=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TLg6CDNpqCyPp5VkNpDaLZ8nPaquE5ZOqUnkPfqTk1uuYaOXr5OK0kEqrYFhnkAR1 VHD0Uj6qkaNhALIJx7T0046QO2hW12Rw1JOWboIr5KkZRKD8KJ3cAe5FlOH54K7pEu EV5UFE08w0CJoL0c7+34CM0V/00xlKyEOG7W+2kdoZNTNdmxAMM8ZkCEg4HXedNcqP q9vpybnkxwgIOOPAAsvGYxoSvCfcQBJ0aMLUma5f8Qy/PAr6jGvcvkDRbaeeft82OU Wqt+hZVEvSVIl/a5Z5DcMBkm+c0DUx3AjmBGVsv789u2F+kxK0x1y3TziCU5aXjGTk exEZ4sjOd/k6Q== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 6/9] tracing/probes: Add string type check with BTF Date: Mon, 7 Aug 2023 11:55:28 +0900 Message-Id: <169137692859.271367.1246073860610569505.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773538746012131375 X-GMAIL-MSGID: 1773538746012131375 From: Masami Hiramatsu (Google) Add a string type checking with BTF information if possible. This will check whether the given BTF argument (and field) is signed char array or pointer to signed char. If not, it reject the 'string' type. If it is pointer to signed char, it adds a dereference opration so that it can correctly fetch the string data from memory. # echo 'f getname_flags%return retval->name:string' >> dynamic_events # echo 't sched_switch next->comm:string' >> dynamic_events The above cases, 'struct filename::name' is 'char *' and 'struct task_struct::comm' is 'char []'. But in both case, user can specify ':string' to fetch the string data. Signed-off-by: Masami Hiramatsu (Google) --- Changes in v3: - Use ctx->btf instead of traceprobe_get_btf(). --- kernel/trace/trace_probe.c | 89 +++++++++++++++++++++++++++++++++++++++++++- kernel/trace/trace_probe.h | 3 + 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 7345e1af4db2..4dc74d73fc1d 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -310,6 +310,77 @@ static u32 btf_type_int(const struct btf_type *t) return *(u32 *)(t + 1); } +static bool btf_type_is_char_ptr(struct btf *btf, const struct btf_type *type) +{ + const struct btf_type *real_type; + u32 intdata; + s32 tid; + + real_type = btf_type_skip_modifiers(btf, type->type, &tid); + if (!real_type) + return false; + + if (BTF_INFO_KIND(real_type->info) != BTF_KIND_INT) + return false; + + intdata = btf_type_int(real_type); + return !(BTF_INT_ENCODING(intdata) & BTF_INT_SIGNED) + && BTF_INT_BITS(intdata) == 8; +} + +static bool btf_type_is_char_array(struct btf *btf, const struct btf_type *type) +{ + const struct btf_type *real_type; + const struct btf_array *array; + u32 intdata; + s32 tid; + + if (BTF_INFO_KIND(type->info) != BTF_KIND_ARRAY) + return false; + + array = (const struct btf_array *)(type + 1); + + real_type = btf_type_skip_modifiers(btf, array->type, &tid); + + intdata = btf_type_int(real_type); + return !(BTF_INT_ENCODING(intdata) & BTF_INT_SIGNED) + && BTF_INT_BITS(intdata) == 8; +} + +static int check_prepare_btf_string_fetch(char *typename, + struct fetch_insn **pcode, + struct traceprobe_parse_context *ctx) +{ + struct btf *btf = ctx->btf; + + if (!btf || !ctx->last_type) + return 0; + + /* char [] does not need any change. */ + if (btf_type_is_char_array(btf, ctx->last_type)) + return 0; + + /* char * requires dereference the pointer. */ + if (btf_type_is_char_ptr(btf, ctx->last_type)) { + struct fetch_insn *code = *pcode + 1; + + if (code->op == FETCH_OP_END) { + trace_probe_log_err(ctx->offset, TOO_MANY_OPS); + return -E2BIG; + } + if (typename[0] == 'u') + code->op = FETCH_OP_UDEREF; + else + code->op = FETCH_OP_DEREF; + code->offset = 0; + *pcode = code; + return 0; + } + /* Other types are not available for string */ + trace_probe_log_err(ctx->offset, BAD_TYPE4STR); + return -EINVAL; +} + static const char *fetch_type_from_btf_type(struct btf *btf, const struct btf_type *type, struct traceprobe_parse_context *ctx) @@ -675,6 +746,13 @@ static int parse_btf_bitfield(struct fetch_insn **pcode, #define find_fetch_type_from_btf_type(ctx) \ find_fetch_type(NULL, ctx->flags) +static int check_prepare_btf_string_fetch(char *typename, + struct fetch_insn **pcode, + struct traceprobe_parse_context *ctx) +{ + return 0; +} + #endif #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) @@ -1117,8 +1195,15 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, /* Update storing type if BTF is available */ if (IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS) && - !t && ctx->last_type) - parg->type = find_fetch_type_from_btf_type(ctx); + ctx->last_type) { + if (!t) { + parg->type = find_fetch_type_from_btf_type(ctx); + } else if (strstr(t, "string")) { + ret = check_prepare_btf_string_fetch(t, &code, ctx); + if (ret) + goto fail; + } + } ret = -EINVAL; /* Store operation */ diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 9184c84833f8..7f929482e8d4 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -513,7 +513,8 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, C(NOSUP_DAT_ARG, "Non pointer structure/union argument is not supported."),\ C(BAD_HYPHEN, "Failed to parse single hyphen. Forgot '>'?"), \ C(NO_BTF_FIELD, "This field is not found."), \ - C(BAD_BTF_TID, "Failed to get BTF type info."), + C(BAD_BTF_TID, "Failed to get BTF type info."),\ + C(BAD_TYPE4STR, "This type does not fit for string."), #undef C #define C(a, b) TP_ERR_##a From patchwork Mon Aug 7 02:55:38 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: 131650 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1209827vqr; Sun, 6 Aug 2023 20:50:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFYMhXRtZvIM/FvHujIvstb1e+TbFSIPmV23+L4APlY47UFwuLIr9ScQAQP9SNVNx4wWqC2 X-Received: by 2002:a17:906:e:b0:99c:7134:ab6d with SMTP id 14-20020a170906000e00b0099c7134ab6dmr7029421eja.41.1691380237538; Sun, 06 Aug 2023 20:50:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691380237; cv=none; d=google.com; s=arc-20160816; b=GFRlejjOAfrerJsImyol6aiqEed0zgHE9sWFr1Qq6WyIU8FM9jYPyGvU55+oCwmfSV vVKdNoAv1Fi1xpSfvbqGCP+jbVnt8bw5Lrkvrbu6se2o/2ztUjcll9i3aqX6KDI3OCWi i3HMdwdyPanVHd8I/yUAwT5Xi0ySQzqmyK+xptqxU4UDbvDcyaENQSZasWbQG/HCaI7g 1+ci8s/2y3KjxgspESsMZiw9x+5igyQk3ZOTJbfwXIcb0NIk+f4quy5W3SV4mK5b6Pq1 qk550dj8DHQoxjcxODx+6u52iqJqTpCm6BFyfjHQsSozrRa7hGJ6tNSv2YnCuVAVb/l1 d60A== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=N0VZdmIcCwbsUXtz78ks4IDAk2qeba7vipWibt19+c4=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=ITdXGOXFMHJxvQnxrnRMWa60CeNHQLyP3VTWz/0KXQ59nP02BeFCSG0qr9oRnHSru6 iJnaVpP52pjbidbHfCU0GUmeiDYnlqR2Amq32hnioLIqFn2z3wUblmj7mVbRSo9fybkb LWZ+wMzaBW1wIpgF13s6+vsCikH36XEpa0Q7NfS3D9d+s+eGAnoFL7Yj1N54h5dIGQk9 8NGiqDO+4aTSy4DPVepLvXsPNtVUfy7kvQVDoQNFZFH+y8haTD9Kxh62GK/6rQHOTgXL vjxgpw1n2WaBKD5rVqF2vr7PO2+9HeeZ38u3fUiJu+3Ws2yfP6y9KPTWfLwSRBmKhOWM zX0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=m8kJkHWo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k5-20020a1709063fc500b0098d52a2bc16si5510705ejj.438.2023.08.06.20.50.04; Sun, 06 Aug 2023 20:50:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=m8kJkHWo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229690AbjHGC4W (ORCPT + 99 others); Sun, 6 Aug 2023 22:56:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48962 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229966AbjHGC4T (ORCPT ); Sun, 6 Aug 2023 22:56:19 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD8431BDA; Sun, 6 Aug 2023 19:55:44 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8DBFF60A4B; Mon, 7 Aug 2023 02:55:43 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2FDA7C433C8; Mon, 7 Aug 2023 02:55:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376943; bh=gcAsXcNpHr2neQoiFwF9exmEBvK8RQO7NJB0uoPDuFA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=m8kJkHWo1ZCZN67vC77Y1xjVj/QZdd7HEOmFmNVl7MijaFHWbLZcKL+dqdDstAalz 8alWXxiJoI7N4Zl+6ArHCH8sFfKRsNjzNBNUQoiT5i+RdsoBYwZGffZtIfwM0mv53C P1wYK7TvF5qDSa7CDpm8juPvvAKCYrUDFwbN4rtLHyj7hPt1HGqxr7iXrXweE2GAZM tGxkCbK+y7WrGleUzkjx0aaz+Cvb8OeR2zqiK07ZRFc0m372nYKOrt1C8Bqu0+KP+k KHEJ44pJHWFAONwnDfeapJZdHZKlJotNoYHzgmF05rx1gyM9+6Sgld7rsQW44ljPpH zR8YOVkhRZkpg== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 7/9] tracing/fprobe-event: Assume fprobe is a return event by $retval Date: Mon, 7 Aug 2023 11:55:38 +0900 Message-Id: <169137693852.271367.5757753088603858125.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773540723921081246 X-GMAIL-MSGID: 1773540723921081246 From: Masami Hiramatsu (Google) Assume the fprobe event is a return event if there is $retval is used in the probe's argument without %return. e.g. echo 'f:myevent vfs_read $retval' >> dynamic_events then 'myevent' is a return probe event. Suggested-by: Steven Rostedt Signed-off-by: Masami Hiramatsu (Google) --- kernel/trace/trace_fprobe.c | 58 +++++++++++++++----- .../ftrace/test.d/dynevent/fprobe_syntax_errors.tc | 2 - 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 8f43f1f65b1b..8bfe23af9c73 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -898,6 +898,46 @@ static struct tracepoint *find_tracepoint(const char *tp_name) return data.tpoint; } +static int parse_symbol_and_return(int argc, const char *argv[], + char **symbol, bool *is_return, + bool is_tracepoint) +{ + char *tmp = strchr(argv[1], '%'); + int i; + + if (tmp) { + int len = tmp - argv[1]; + + if (!is_tracepoint && !strcmp(tmp, "%return")) { + *is_return = true; + } else { + trace_probe_log_err(len, BAD_ADDR_SUFFIX); + return -EINVAL; + } + *symbol = kmemdup_nul(argv[1], len, GFP_KERNEL); + } else + *symbol = kstrdup(argv[1], GFP_KERNEL); + if (!*symbol) + return -ENOMEM; + + if (*is_return) + return 0; + + /* If there is $retval, this should be a return fprobe. */ + for (i = 2; i < argc; i++) { + tmp = strstr(argv[i], "$retval"); + if (tmp && !isalnum(tmp[7]) && tmp[7] != '_') { + *is_return = true; + /* + * NOTE: Don't check is_tracepoint here, because it will + * be checked when the argument is parsed. + */ + break; + } + } + return 0; +} + static int __trace_fprobe_create(int argc, const char *argv[]) { /* @@ -927,7 +967,7 @@ static int __trace_fprobe_create(int argc, const char *argv[]) struct trace_fprobe *tf = NULL; int i, len, new_argc = 0, ret = 0; bool is_return = false; - char *symbol = NULL, *tmp = NULL; + char *symbol = NULL; const char *event = NULL, *group = FPROBE_EVENT_SYSTEM; const char **new_argv = NULL; int maxactive = 0; @@ -983,20 +1023,10 @@ static int __trace_fprobe_create(int argc, const char *argv[]) trace_probe_log_set_index(1); /* a symbol(or tracepoint) must be specified */ - symbol = kstrdup(argv[1], GFP_KERNEL); - if (!symbol) - return -ENOMEM; + ret = parse_symbol_and_return(argc, argv, &symbol, &is_return, is_tracepoint); + if (ret < 0) + goto parse_error; - tmp = strchr(symbol, '%'); - if (tmp) { - if (!is_tracepoint && !strcmp(tmp, "%return")) { - *tmp = '\0'; - is_return = true; - } else { - trace_probe_log_err(tmp - symbol, BAD_ADDR_SUFFIX); - goto parse_error; - } - } if (!is_return && maxactive) { trace_probe_log_set_index(0); trace_probe_log_err(1, BAD_MAXACT_TYPE); diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc index 812f5b3f6055..72563b2e0812 100644 --- a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc @@ -30,11 +30,11 @@ check_error 'f:^ vfs_read' # NO_EVENT_NAME check_error 'f:foo/^12345678901234567890123456789012345678901234567890123456789012345 vfs_read' # EVENT_TOO_LONG check_error 'f:foo/^bar.1 vfs_read' # BAD_EVENT_NAME -check_error 'f vfs_read ^$retval' # RETVAL_ON_PROBE check_error 'f vfs_read ^$stack10000' # BAD_STACK_NUM check_error 'f vfs_read ^$arg10000' # BAD_ARG_NUM +check_error 'f vfs_read $retval ^$arg1' # BAD_VAR check_error 'f vfs_read ^$none_var' # BAD_VAR check_error 'f vfs_read ^'$REG # BAD_VAR From patchwork Mon Aug 7 02:55:48 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: 131661 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1222985vqr; Sun, 6 Aug 2023 21:35:53 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEcGDIXS2kcyKzuMmoB1Q9s4vUvkJLKgxveNo9yLeymbZwPciBYO8pkn7VX5t+3YhmDOBBm X-Received: by 2002:a17:907:78cb:b0:994:5340:22f4 with SMTP id kv11-20020a17090778cb00b00994534022f4mr7622213ejc.6.1691382953191; Sun, 06 Aug 2023 21:35:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691382953; cv=none; d=google.com; s=arc-20160816; b=PlVDsR+8L24Syc8ypyJpKKpwmm8JVQpUP08uDOwhk95dBwA3LMRSq+wOR+vxbyQjtX dPiC/s5LHkUVvgilxpkHhA1IcObrGYRf7dFlAjJHuLiqrGD3v0HcvNndoC7heWLDNHcg lmHwhjPqnJ0a3jiW7EueIcNQqa+YjSXiZ9SLAeQexfLiePFupB1MQyq3TmOY97sjDofg vAJNk6yBG/l6JUHZA42oHUIJ2rlvnk//QoCRFuNiX80mCodI1zQalgLAugNXVoZnUaor nPOAMczIhtK2fn72to+vb5LX2Ff0PqkSYQKgQoBHYkayZs+81/wRClfjHKFnBz04C6gd cW6w== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=qm1ANc6QUeHzRuz86zCsJ53UVdqX7UUgfQGBeWLQ6ZA=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=ZyrdWbMFe+GQNPYTQTcrD/wYcshTmWKoi5m8+ck5AqKeGiKutgaTyF65y54JfMcr0w SZ+npAg1K4IcteM2FxJf6PjLiVB2KUhjNaFfJl2NBy++2MT7VNHnTU7z3AG39BA3hy1v 4cIWTJhcBJG8ze1A4+W7dR7aLc9weYhurjvJ6mkbhQloVZJh24EQlIP0iGEvJf7UwH0K nKAcJN00nTsbudaSo1Hj9BeKdmoPvv433VDo99Imk75bV0Fx9I9UFHGH9gIUnzXa3T4k 59mWHobE/xqH3cI/dyUA3Gcb6TRQqcEvAwQzTvrKRJp+OcfiFZqLddEJS0Fn8O+IksKQ 64FQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WnYTCRr1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g12-20020a17090613cc00b0099364d9f0e0si4773153ejc.540.2023.08.06.21.35.27; Sun, 06 Aug 2023 21:35:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WnYTCRr1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229558AbjHGC4i (ORCPT + 99 others); Sun, 6 Aug 2023 22:56:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229976AbjHGC40 (ORCPT ); Sun, 6 Aug 2023 22:56:26 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2365B1733; Sun, 6 Aug 2023 19:55:57 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 9A1526133A; Mon, 7 Aug 2023 02:55:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05FE5C433C7; Mon, 7 Aug 2023 02:55:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376953; bh=rmxZE83d3FXHRV2guA/jsebhw3LfN+eEvFVGseZCh3Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WnYTCRr1Lss7WR/d5AJQW78eAGilsSVBOaKHG+hpnKM2wB7vUxBgcYYolWgAkJc2I lqE6mV9rwSCLhZVsmgJNIBcySKQ+dbaHFw/kLhdGvySDg2gOwfXwV6bFWak9ONysmt SSti2LMCUdHSdL6H605JndN4N6BneEQuaboVNr5OiSTQW4fAmFY+WOMcVNUniriw+Z 9d8dFQob/b5SuMH7nHB2Oryp7xSsoLjrkePhQhjYFQQtrBHBCnPoYnEIJaW70JFmDh IbSL9rolpHsyXCwWEzKzuZOfHJ/2oR6kZoI7rEQYN9JX0BCqog+DemIUY1n0v8DfM7 xnWLZQhyvw2PA== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 8/9] selftests/ftrace: Add BTF fields access testcases Date: Mon, 7 Aug 2023 11:55:48 +0900 Message-Id: <169137694835.271367.10787741563925762942.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773543571601188046 X-GMAIL-MSGID: 1773543571601188046 From: Masami Hiramatsu (Google) Add test cases for accessing the data structure fields using BTF info. This includes the field access from parameters and retval, and accessing string information. Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Alan Maguire --- Changes in v2: - Use '$retval' instead of 'retval'. - Add a test that use both '$retval' and '$arg1' for fprobe. Changes in v3: - Change a test case with a numeric value. - Add a test case with mixed '.' and '->' operators. Changes in v5: - Check fields access availability. --- .../ftrace/test.d/dynevent/add_remove_btfarg.tc | 20 ++++++++++++++++++++ .../ftrace/test.d/dynevent/fprobe_syntax_errors.tc | 8 ++++++++ 2 files changed, 28 insertions(+) diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_btfarg.tc b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_btfarg.tc index f34b14ef9781..b9c21a81d248 100644 --- a/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_btfarg.tc +++ b/tools/testing/selftests/ftrace/test.d/dynevent/add_remove_btfarg.tc @@ -5,6 +5,7 @@ KPROBES= FPROBES= +FIELDS= if grep -qF "p[:[/][]] []" README ; then KPROBES=yes @@ -12,6 +13,9 @@ fi if grep -qF "f[:[/][]] [%return] []" README ; then FPROBES=yes fi +if grep -qF "[->field[->field|.field...]]" README ; then + FIELDS=yes +fi if [ -z "$KPROBES" -a -z "$FPROBES" ] ; then exit_unsupported @@ -21,6 +25,9 @@ echo 0 > events/enable echo > dynamic_events TP=kfree +TP2=kmem_cache_alloc +TP3=getname_flags +TP4=sched_wakeup if [ "$FPROBES" ] ; then echo "f:fpevent $TP object" >> dynamic_events @@ -33,6 +40,7 @@ echo > dynamic_events echo "f:fpevent $TP "'$arg1' >> dynamic_events grep -q "fpevent.*object=object" dynamic_events + echo > dynamic_events echo "f:fpevent $TP "'$arg*' >> dynamic_events @@ -45,6 +53,18 @@ fi echo > dynamic_events +if [ "$FIELDS" ] ; then +echo "t:tpevent ${TP2} obj_size=s->object_size" >> dynamic_events +echo "f:fpevent ${TP3}%return path=\$retval->name:string" >> dynamic_events +echo "t:tpevent2 ${TP4} p->se.group_node.next->prev" >> dynamic_events + +grep -q "tpevent .*obj_size=s->object_size" dynamic_events +grep -q "fpevent.*path=\$retval->name:string" dynamic_events +grep -q 'tpevent2 .*p->se.group_node.next->prev' dynamic_events + +echo > dynamic_events +fi + if [ "$KPROBES" ] ; then echo "p:kpevent $TP object" >> dynamic_events grep -q "kpevent.*object=object" dynamic_events diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc index 72563b2e0812..20e42c030095 100644 --- a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc @@ -103,6 +103,14 @@ check_error 'f vfs_read%return ^$arg*' # NOFENTRY_ARGS check_error 'f vfs_read ^hoge' # NO_BTFARG check_error 'f kfree ^$arg10' # NO_BTFARG (exceed the number of parameters) check_error 'f kfree%return ^$retval' # NO_RETVAL + +if grep -qF "[->field[->field|.field...]]" README ; then +check_error 'f vfs_read%return $retval->^foo' # NO_PTR_STRCT +check_error 'f vfs_read file->^foo' # NO_BTF_FIELD +check_error 'f vfs_read file^-.foo' # BAD_HYPHEN +check_error 'f vfs_read ^file:string' # BAD_TYPE4STR +fi + else check_error 'f vfs_read ^$arg*' # NOSUP_BTFARG check_error 't kfree ^$arg*' # NOSUP_BTFARG From patchwork Mon Aug 7 02:55:58 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: 131653 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1211421vqr; Sun, 6 Aug 2023 20:57:12 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFQbQJ7QJOQJ7NH+2WePBiQe4s9IMH1bBrsJd8VcIgJ7PQ+as2+VSC1idvYtdUnOKvRUudl X-Received: by 2002:a05:6402:1a32:b0:522:29c9:d30 with SMTP id be18-20020a0564021a3200b0052229c90d30mr7922833edb.10.1691380632347; Sun, 06 Aug 2023 20:57:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691380632; cv=none; d=google.com; s=arc-20160816; b=C2EOKJbJXXhpra2kLGK4HuVUQ374Sge9WEw+1WGXvYWQwc1SOgHCoFkIUDO/xMBEFZ jqRw0T0qoBw/sKrbpbenOtpRk446ADTzo1b7JPLvdR6qsD6fr1/Dis8Knr7IYrm2vzoe P4z26QosAPb3zbaODmP1Suci+jYdFHUGnF8DNQoBnmcU9MM+i1vMbutkWFtvvaxV8HvM UJTOQdM0crH8i26iBAN6HhR83wsQDHkuz9j0iXTtiMCQ6DPFcS7Mt3JBhxg1wzWA3RpG YG2sHn19Hzc1MqU9C/tEyXChpQ6uyyEdSx/Z7NLcXPubfruteh2zSIItF46qACraXrA7 edDA== 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:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Nhv0fMyByyMrlK8yFYQh43STKZphpezVS0+jtbTBXXw=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=H3MkFHBFHt19x1wUc+0ZJR1ah/pHWafuc7xUfx3abhByLe0twT1tpVzxLhfAVwPSN7 OB6yRGUAW4fdV4DUTTLavHvt1OI8RvoQrx9WNxrvUlWThgShHvJGUtnCXCf0jOR7tCKJ niQMVeLyF5FQssSZS6yJuKYQwXsG8Iyr6mX3t5dKiBDhdNUYmKXqBFIicp2UYTe08SXG hFkZP0cOdjjP/lVavOwBnuwmDkRVQacj8JyUF7wLo7i8PyVxrnT7Gpp03KQ4fGPStWQ8 I/2gb6UYpSslBsGYIPNFxEW0qrnjvnEl1jKMZhvUs/1jnfoOvAvk7ggO0u6kT2q8gtNV 0TCQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hO36a7Gj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bm22-20020a0564020b1600b0052336318cf8si1418016edb.636.2023.08.06.20.56.48; Sun, 06 Aug 2023 20:57:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hO36a7Gj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229956AbjHGC4u (ORCPT + 99 others); Sun, 6 Aug 2023 22:56:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49390 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229726AbjHGC4n (ORCPT ); Sun, 6 Aug 2023 22:56:43 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3BD751FCB; Sun, 6 Aug 2023 19:56:15 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id ACE406135F; Mon, 7 Aug 2023 02:56:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 27AEDC433C7; Mon, 7 Aug 2023 02:56:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691376963; bh=CcGORqTI9ZQHAZplK151N2vLhAMfOhssOSPkNJphVGw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hO36a7Gjpv8QJdB8m0hmFDhyJLJphDptKNqTvpcNk6jT2nptYn7C2w6rEprOVhkdL ScImftyUWs+zRKz5EsAPliJMBjQ2d5GAKE0rvTwczYk752TMLocbuzoZvbyecWMT68 jaF0E7hltX/KB57w77FmPABsQ1DhSOlQP9OjLQYPrhxL3/JH49EK5jxQC8FWJK2o7q mfjFAjBfEqxlknKcE/fWEVHXp+aD3rPOpbWV5PKd7IewsDByLZQNM61DKIl8zCIuNx IhbVP0XkMlyz3oKGLxqNqF84klX81eyqx6PMtVzsTLZhYfG2UjAM70lYXewskLrkgC hps8z4n+DHJ0A== From: "Masami Hiramatsu (Google)" To: linux-trace-kernel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Steven Rostedt , mhiramat@kernel.org, Martin KaFai Lau , bpf@vger.kernel.org, Sven Schnelle , Alexei Starovoitov Subject: [PATCH v5 9/9] Documentation: tracing: Update fprobe event example with BTF field Date: Mon, 7 Aug 2023 11:55:58 +0900 Message-Id: <169137695840.271367.4018951814702424256.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169137686814.271367.11218568219311636206.stgit@devnote2> References: <169137686814.271367.11218568219311636206.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773541137834017960 X-GMAIL-MSGID: 1773541137834017960 From: Masami Hiramatsu (Google) Update fprobe event example with BTF data structure field specification. Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Alan Maguire --- Changes in v2: - Remove 'retval' and use '$retval'. Changes in v3: - Add description about mixture of '.' and '->' usage. --- Documentation/trace/fprobetrace.rst | 64 +++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/Documentation/trace/fprobetrace.rst b/Documentation/trace/fprobetrace.rst index 7297f9478459..8e9bebcf0a2e 100644 --- a/Documentation/trace/fprobetrace.rst +++ b/Documentation/trace/fprobetrace.rst @@ -79,9 +79,9 @@ automatically set by the given name. :: f:fprobes/myprobe vfs_read count=count pos=pos It also chooses the fetch type from BTF information. For example, in the above -example, the ``count`` is unsigned long, and the ``pos`` is a pointer. Thus, both -are converted to 64bit unsigned long, but only ``pos`` has "%Lx" print-format as -below :: +example, the ``count`` is unsigned long, and the ``pos`` is a pointer. Thus, +both are converted to 64bit unsigned long, but only ``pos`` has "%Lx" +print-format as below :: # cat events/fprobes/myprobe/format name: myprobe @@ -105,9 +105,47 @@ is expanded to all function arguments of the function or the tracepoint. :: # cat dynamic_events f:fprobes/myprobe vfs_read file=file buf=buf count=count pos=pos -BTF also affects the ``$retval``. If user doesn't set any type, the retval type is -automatically picked from the BTF. If the function returns ``void``, ``$retval`` -is rejected. +BTF also affects the ``$retval``. If user doesn't set any type, the retval +type is automatically picked from the BTF. If the function returns ``void``, +``$retval`` is rejected. + +You can access the data fields of a data structure using allow operator ``->`` +(for pointer type) and dot operator ``.`` (for data structure type.):: + +# echo 't sched_switch preempt prev_pid=prev->pid next_pid=next->pid' >> dynamic_events + +The field access operators, ``->`` and ``.`` can be combined for accessing deeper +members and other structure members pointed by the member. e.g. ``foo->bar.baz->qux`` +If there is non-name union member, you can directly access it as the C code does. +For example:: + + struct { + union { + int a; + int b; + }; + } *foo; + +To access ``a`` and ``b``, use ``foo->a`` and ``foo->b`` in this case. + +This data field access is available for the return value via ``$retval``, +e.g. ``$retval->name``. + +For these BTF arguments and fields, ``:string`` and ``:ustring`` change the +behavior. If these are used for BTF argument or field, it checks whether +the BTF type of the argument or the data field is ``char *`` or ``char []``, +or not. If not, it rejects applying the string types. Also, with the BTF +support, you don't need a memory dereference operator (``+0(PTR)``) for +accessing the string pointed by a ``PTR``. It automatically adds the memory +dereference operator according to the BTF type. e.g. :: + +# echo 't sched_switch prev->comm:string' >> dynamic_events +# echo 'f getname_flags%return $retval->name:string' >> dynamic_events + +The ``prev->comm`` is an embedded char array in the data structure, and +``$retval->name`` is a char pointer in the data structure. But in both +cases, you can use ``:string`` type to get the string. + Usage examples -------------- @@ -161,10 +199,10 @@ parameters. This means you can access any field values in the task structure pointed by the ``prev`` and ``next`` arguments. For example, usually ``task_struct::start_time`` is not traced, but with this -traceprobe event, you can trace it as below. +traceprobe event, you can trace that field as below. :: - # echo 't sched_switch comm=+1896(next):string start_time=+1728(next):u64' > dynamic_events + # echo 't sched_switch comm=next->comm:string next->start_time' > dynamic_events # head -n 20 trace | tail # TASK-PID CPU# ||||| TIMESTAMP FUNCTION # | | | ||||| | | @@ -176,13 +214,3 @@ traceprobe event, you can trace it as below. -0 [000] d..3. 5606.690317: sched_switch: (__probestub_sched_switch+0x4/0x10) comm="kworker/0:1" usage=1 start_time=137000000 kworker/0:1-14 [000] d..3. 5606.690339: sched_switch: (__probestub_sched_switch+0x4/0x10) comm="swapper/0" usage=2 start_time=0 -0 [000] d..3. 5606.692368: sched_switch: (__probestub_sched_switch+0x4/0x10) comm="kworker/0:1" usage=1 start_time=137000000 - -Currently, to find the offset of a specific field in the data structure, -you need to build kernel with debuginfo and run `perf probe` command with -`-D` option. e.g. -:: - - # perf probe -D "__probestub_sched_switch next->comm:string next->start_time" - p:probe/__probestub_sched_switch __probestub_sched_switch+0 comm=+1896(%cx):string start_time=+1728(%cx):u64 - -And replace the ``%cx`` with the ``next``.