From patchwork Wed Jul 26 13:00:03 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: 126371 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp411600vqo; Wed, 26 Jul 2023 06:42:36 -0700 (PDT) X-Google-Smtp-Source: APBJJlE09Tt2ErO2hk4v6cEfoEhPr1Ke0JJuQTBvIYXT9zrL8pyCRD27jNrWNJxT8XiTHCBuWGrF X-Received: by 2002:a17:902:9a4a:b0:1bb:1523:b2d7 with SMTP id x10-20020a1709029a4a00b001bb1523b2d7mr1453854plv.14.1690378956391; Wed, 26 Jul 2023 06:42:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690378956; cv=none; d=google.com; s=arc-20160816; b=PpKMzKDP6Nqijx52NX1elsntdGP2Zy33+JJSXoC1qfeyAQ1hSrPWmaIQDPv3BQrIpC ZAan95qXU3MMGj5M0k7FH7sMVFxPO2ixH0b8KSunRsG6gKeUyQ+DUdJwaF6ZajxWD4In h5GfVwAA62gih8FjmQrC6imwnkpqUMgUYH12Levx6ALnIHp3ATQwQwkumthDK7KrhLcs sU2lI4MYEzhvku26FyvdCfQU3jGTn3L15A7AcViF+H322sjda37bdX1+OSieqUO1ElLB 1ZWDUr9SZwfpJjvHSMDF2wXvQWoTWqtBCarH3jBm9edekmf6d9C0qEgN358CUtr1IaiL NXKg== 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=d3tj/ACpxGyzzu3n+pzGss3TZTJE0n/AOr9sCQMsBeeCk2zbSU0cb08g3jz9VMR08d oov/0S+9fRCmEy/DYnAFvQVWFBtpjbbrkzQm9uzKQqz4zSYC3MytE8QsOf1baICHmA1+ xUyJMO7Z8gsp9ozRHwf7fc5xlK7xh2WcDh18Z1rVzwJYPu5Sogc2iYmx+C3vk/PWL2R/ q7XYS3wHqmjp7N7V9vIL131C1K/XIn8Wo8FSyTeqejPhowBtRP+1h2mtOylYJzBCUH3H BKguiFFtr2p85IV55GmlR3FCdOOtCYb80BOtgcMr/JU+KXmqYNd7Oyxi0jNnSsdtMTfq bnpw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=HnCw+TfQ; 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 ij29-20020a170902ab5d00b001b8a39d1738si8949797plb.500.2023.07.26.06.42.22; Wed, 26 Jul 2023 06:42:36 -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=HnCw+TfQ; 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 S233029AbjGZNAN (ORCPT + 99 others); Wed, 26 Jul 2023 09:00:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232768AbjGZNAL (ORCPT ); Wed, 26 Jul 2023 09:00:11 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52A151BD6; Wed, 26 Jul 2023 06:00:09 -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 D4C3E617A1; Wed, 26 Jul 2023 13:00:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4093DC433C8; Wed, 26 Jul 2023 13:00:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376408; bh=KReumcvfAA7aUU41c/MWj+LowvbdvMSmvuGEweZl3FI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HnCw+TfQ23Rn7ZiLnwz3oZItW3yIZLX+9dBO2r4xfoDpoRXmLzuqFU/ugELZ24tBW lzrtFr+1PpnU+D+OS4OduxX+CNh+yoyUS4E52yWVN1lL8tqtHbWoFbqXqLbgstgok3 N4WcItIc+ez1FA76YTrdlTFKiMSdoJTYVT2nLMtOegfpttP+zTaF3mcUg1yGTMJNte DSzVQPNrv3sfNnQSPcIsSMmbdfiAEQRsJGavTtoNMZ/CcDLzzSWRZl2wMpWpVgQHUw C0UD+piWXQpzhMH//WjBHa+ow5dZ7m0vVDWyFyLisNElrf00NhHkPyJm20C7YzDvG+ 0yLwdZ6T2Fr5g== 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 v3 1/9] tracing/probes: Support BTF argument on module functions Date: Wed, 26 Jul 2023 22:00:03 +0900 Message-Id: <169037640364.607919.7818982786099472934.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772490804549684167 X-GMAIL-MSGID: 1772490804549684167 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 Wed Jul 26 13:00:13 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: 126352 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp396170vqo; Wed, 26 Jul 2023 06:17:07 -0700 (PDT) X-Google-Smtp-Source: APBJJlHY0svEpL77+D8H16fFuu9DWyu25YO0maxIdZxwHYzuFSrD+gu4W4SGRFMksMtyslzWoMb4 X-Received: by 2002:a2e:a168:0:b0:2b4:83c3:d285 with SMTP id u8-20020a2ea168000000b002b483c3d285mr1585295ljl.38.1690377426841; Wed, 26 Jul 2023 06:17:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690377426; cv=none; d=google.com; s=arc-20160816; b=BnuovXS5HVgA1rsWyUNJiRK1m7C98wcpCFkCa6ZYdQkvl9SSE9548KkpsZolvTSkhG gvl31VwSrZmk0PIOqKIwIPV9hB7YWYDh6zRn+HKZ0op5DuUOaApUIaWY1ck1+QGnKT+Q vLzobP+WWefg/vbJIdH8tXMEreNNBsMfhg1oAYC5jQuTkuGUoruuXmh/hGfRCe7txryA drzQMPV0ea8RfXqjvGMMJkPcM/frWPDwiHeVRieMq9lIdUstDx07zRt747ehnZ8+EO+7 P+nlcZ4aPGltpf87G9OwuMuAp3VkFPBK3FY4mQSDoEdaTFeyzWEgQaYsspDtaRISvWfR wmiw== 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=AqItGZxNm5vBReUt1IrarI9tDkPp/4TxJjzBqByVk0c=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=YcOb/XMYSmmg4nVkw6yAeOgB5pcsDfKz5f+wTSUMiDW1cYm6Wk2ztS86QcRDcx9BDC UZFD2cqQOhbhYvf0QUbdH2WWzJMBIA6QTYE9D/Fu0RtUZ3QYYeI/aQxCZjZ7DVMm6oEV FUb8Dkh6yxJENuYsVdAUmLmQm3wwDNzRp8XNP9R5D+V92zqcTtWKEAqvZno3KnPk2QdM zGer+Es87E7KgdZ4aaPBCv92re/OcK1N8VWuNR6sNCfxlU8b1KkbmjOpnD5XoaoFeDd4 LT6ePMS51t+eKp092mWK0119aJFjwFp8hVoogcs7001pp5bTQj+TpT9AcuT3LVeYW2jB +fjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WUPMFPxe; 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 q27-20020a1709060e5b00b009883ee7519fsi8985639eji.884.2023.07.26.06.16.41; Wed, 26 Jul 2023 06:17:06 -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=WUPMFPxe; 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 S233231AbjGZNA1 (ORCPT + 99 others); Wed, 26 Jul 2023 09:00:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58592 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233236AbjGZNAY (ORCPT ); Wed, 26 Jul 2023 09:00:24 -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 1BBDF2129; Wed, 26 Jul 2023 06:00:19 -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 A37CC613CA; Wed, 26 Jul 2023 13:00:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0EA64C433C8; Wed, 26 Jul 2023 13:00:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376418; bh=SVaKMsm5wi9MtePH615CD5h2bQfFDb6xVagKrZjtk0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WUPMFPxeQ243AvvEKB6yR048E2BwbVC2zYeNyQp0MhufnS8soHGi14Yh8wM1dans9 jFh5g5cBlzc5BsVYAq08KU6yMOcJ4mHyg5pxSKWu1M6jXXdGtUdthBvg8H2/nPb7qM J3bLVYkBURe7UL1Elew2+HhnMbguVKY7tgY+X/VkD6Xof0J7pHaFETcpXnmxLY8QeE Ty/Gp7oPQhqfxjteluKERbDnq/oHIlhTrPV0r+/GvGXau42/GAe70Fyj+TVehSMtO3 xIJt66WwEYbJD2WKlfbXVhfN4fi2eQ0ticmjhmWLH3aC94X5vEhWkbgdZBmq8wzkdv IvfS1yQeTAQhQ== 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 v3 2/9] bpf/btf: tracing: Move finding func-proto API and getting func-param API to BTF Date: Wed, 26 Jul 2023 22:00:13 +0900 Message-Id: <169037641366.607919.6661445077432894528.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772489200704027543 X-GMAIL-MSGID: 1772489200704027543 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. --- include/linux/btf.h | 4 ++++ kernel/bpf/btf.c | 47 +++++++++++++++++++++++++++++++++++++++++ kernel/trace/trace_probe.c | 50 +++++++++----------------------------------- 3 files changed, 61 insertions(+), 40 deletions(-) diff --git a/include/linux/btf.h b/include/linux/btf.h index dbfe41a09c4b..20e3a07eef8f 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -222,6 +222,10 @@ const struct btf_type * btf_resolve_size(const struct btf *btf, const struct btf_type *type, u32 *type_size); const char *btf_type_str(const struct btf_type *t); +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); #define for_each_member(i, struct_type, member) \ for (i = 0, member = btf_type_member(struct_type); \ diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index b9b0eb1189bb..f7b25c615269 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -911,6 +911,53 @@ static const struct btf_type *btf_type_skip_qualifiers(const struct btf *btf, return t; } +/* + * Find a function proto type by name, and return the btf_type with its btf + * in *@btf_p. Return NULL if not found. + * Note that caller has to call btf_put(*@btf_p) after using the btf_type. + */ +const struct btf_type *btf_find_func_proto(const char *func_name, struct btf **btf_p) +{ + const struct btf_type *t; + s32 id; + + id = bpf_find_btf_id(func_name, BTF_KIND_FUNC, btf_p); + if (id < 0) + return NULL; + + /* Get BTF_KIND_FUNC type */ + t = btf_type_by_id(*btf_p, id); + if (!t || !btf_type_is_func(t)) + goto err; + + /* The type of BTF_KIND_FUNC is BTF_KIND_FUNC_PROTO */ + t = btf_type_by_id(*btf_p, t->type); + if (!t || !btf_type_is_func_proto(t)) + goto err; + + return t; +err: + btf_put(*btf_p); + return NULL; +} + +/* + * Get function parameter with the number of parameters. + * This can return NULL if the function has no parameters. + * It can return -EINVAL if the @func_proto is not a function proto type. + */ +const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, s32 *nr) +{ + if (!btf_type_is_func_proto(func_proto)) + return ERR_PTR(-EINVAL); + + *nr = btf_type_vlen(func_proto); + if (*nr > 0) + return (const struct btf_param *)(func_proto + 1); + else + return NULL; +} + #define BTF_SHOW_MAX_ITER 10 #define BTF_KIND_BIT(kind) (1ULL << kind) diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index ecbe28f8d676..21a228d88ebb 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -361,38 +361,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 +371,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 +390,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 +466,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 +482,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 Wed Jul 26 13:00:23 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: 126367 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp410580vqo; Wed, 26 Jul 2023 06:40:49 -0700 (PDT) X-Google-Smtp-Source: APBJJlEJLUvA1xa6ogX6O+O4wHEU/s6oTRMGHPt4lZPaXqcXyE4YFonWgJ2lZf3a+J4Z4pFOC5fX X-Received: by 2002:a05:6a20:7286:b0:133:dd1b:aa57 with SMTP id o6-20020a056a20728600b00133dd1baa57mr1857283pzk.18.1690378849281; Wed, 26 Jul 2023 06:40:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690378849; cv=none; d=google.com; s=arc-20160816; b=TZcMU4CrHdZgGX7jzZgCq0IqxAs+xhiFzeiRBPduLZuRDzGDO8eYAYR48k346xPMYB +ZBTM6Tm4FQiT3M4/E6GnIJqsh39/RfNQpxv2d7+FZWPt43qKrD0WBvQ4+NUdPXgZtUE 2YFbxZ0M44CRxL7CG66cmzyGtWm3qV+n4qYhHAJHRoy5MyIQqbiyvVJLL+t7goTzNAkJ RjDWKT30OVRDa1bwYACA4XmWhgrWY3jvrSI8tHkxrfHq+XIIxwOM71ftHsyYFOvjJiDY LVV8PVhl8vDQVcapFMRw+uDOdUv8ChOe1sqhmFtiXkSLQdcYdRQkAEG6R1sNiEDSEF8k KzgA== 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=cEGwK1Km35jMNVmsD9RxNew+6KHbYc9Z6g2VSX5SFuM=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=0UtX1cwxyicTYt92XGhXj/f4yA/mLOu6xFAT/nfRvVeOxsbOD32c2sSXmXA//jezmr SUZk1w0CWLgNLb6MQNpbIpLg4tTiw2dQhEBG3Xprn8WODcR+uNIBE/xckg10GfWP3vUX niJs33DQ/GRnxQmFrcn1Plv0FPBX9obvUipbk9eq+eMQqfgDyA0DWFPRPe4UmBCqW/am OLqBJkvyX6yYDBK8DMg//ld5rhH5RqI4LL9E2zXpI4TNkrZSt1w0feD4+v0w9ZGj9rwv H+JYuhRDnD6NLrcZib5TsIp7lazRQKQh/kLf+Q1Xh+a/aRAG9u7m66CjIbVdllBTYH1J rbzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=u2bN3agz; 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 bs125-20020a632883000000b00543cba6043asi12337824pgb.151.2023.07.26.06.40.35; Wed, 26 Jul 2023 06:40:49 -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=u2bN3agz; 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 S233279AbjGZNAh (ORCPT + 99 others); Wed, 26 Jul 2023 09:00:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233064AbjGZNAc (ORCPT ); Wed, 26 Jul 2023 09:00:32 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B53A31BD6; Wed, 26 Jul 2023 06:00:28 -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 4FF8661A1D; Wed, 26 Jul 2023 13:00:28 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E1FD9C433CA; Wed, 26 Jul 2023 13:00:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376427; bh=DWqlMr8roXaG6O8LFsOi9Etaux6ORDbs/Xvw8dSo2Lk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u2bN3agznoFdF/wMEce7jdyTpYWz8GBbGxgTIcPZJqydyJAektpDOCPqIQh0fJlC4 JWlE1IunzI4uieM1xAE+O0/u3s0QeVPagK9RLHm5vFErscdIxVLqPFFqEmG/smokX4 hDrNXUQtTs9ImiQC3NF24CZboALsPDHqEhyP4nQ/qst8XE5mmb7qkdzvCb4br6hhXa O3afaZZTfvoWkcQztesj3DfKP6od9+IjCDOIZxTCAqCVWbCq5DG6ZkjWkwRqW6wU++ nDft2uFtZTAkq8v9AMK5UHhXTXeV2nIP1eE+PM5xCqZrvEcHuYY6fVYFrORF26EZfd zxsBJSo+9+yQA== 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 v3 3/9] bpf/btf: Add a function to search a member of a struct/union Date: Wed, 26 Jul 2023 22:00:23 +0900 Message-Id: <169037642351.607919.10234149030120807556.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772490692206556473 X-GMAIL-MSGID: 1772490692206556473 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(). --- include/linux/btf.h | 3 +++ kernel/bpf/btf.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/linux/btf.h b/include/linux/btf.h index 20e3a07eef8f..4b10d57ceee0 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -226,6 +226,9 @@ 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); #define for_each_member(i, struct_type, member) \ for (i = 0, member = btf_type_member(struct_type); \ diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index f7b25c615269..5258870030fc 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -958,6 +958,41 @@ const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, s3 return NULL; } +/* + * Find a member of data structure/union by name and return it. + * Return NULL if not found, or -EINVAL if parameter is invalid. + */ +const struct btf_member *btf_find_struct_member(struct btf *btf, + const struct btf_type *type, + const char *member_name) +{ + const struct btf_member *member, *ret; + const char *name; + int i; + + if (!btf_type_is_struct(type)) + return ERR_PTR(-EINVAL); + + for_each_member(i, type, member) { + if (!member->name_off) { + /* unnamed member: dig deeper */ + type = btf_type_skip_modifiers(btf, member->type, NULL); + if (type) { + ret = btf_find_struct_member(btf, type, + member_name); + if (!IS_ERR_OR_NULL(ret)) + return ret; + } + } else { + name = btf_name_by_offset(btf, member->name_off); + if (name && !strcmp(member_name, name)) + return member; + } + } + + return NULL; +} + #define BTF_SHOW_MAX_ITER 10 #define BTF_KIND_BIT(kind) (1ULL << kind) From patchwork Wed Jul 26 13:00:33 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: 126384 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp416013vqo; Wed, 26 Jul 2023 06:49:55 -0700 (PDT) X-Google-Smtp-Source: APBJJlGwB5Jz4AC7TnXQCHtWVaqbJCTbvy2xJJ4vzxSZpa8BP4172yUVCy8BLSdwa9gUOQdqgilG X-Received: by 2002:a2e:9e4c:0:b0:2b6:efa0:7c36 with SMTP id g12-20020a2e9e4c000000b002b6efa07c36mr1536532ljk.21.1690379394693; Wed, 26 Jul 2023 06:49:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690379394; cv=none; d=google.com; s=arc-20160816; b=REnUt2C6hIIrXAecm+Q5WEOxJ57RiLR/X7Ckffeqv0oXghmtwoUib2WX5X2rHpCMOj c8veGB42uAVGqjJ/gE+jwR25cm/FOYIArN1P1dKi3+tLZoXJm5Gqe+m+EBQ9q8clvgYF rWLDgh2zSuJTjYxFp+O02wGwkUbCTlAZMZ+jy8ddCs2FXE16I+dlm/7k1UPQFNE+kp/T i6lrSRC3nwQZZrXDevQsrcfu6gPn1Pxs/HJE4lAk3xCyCEEBBAgdYfeJAuSzim9idMwg 2nmGjpXDje74FtchZj+B3gkapVOR2frpqmXAZUnpfK6+XqTSmTVaqe74wnYEfHqr9fEO Xg6Q== 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=UiKOktUw3US0JFv6s4jmPrJUJomaYToSy0bvf6jMbdQ=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=nH71LlO5IK0s6aZbmz6UD6gT4PLUU2pAW6KKODkoNll1GN4pIS1duYDCADYUm7EgI4 5JG3kGseP3wVca8hkwx28YRRtytBm+2b8388dHUXtHzdenS1a44T4qZ2BUUf+VNLxXnU COtjQFuMUzajbyi2hRIZmHG0niadGhvob+V1G8WptVQdy+2xS0xdUizka9p/b+RUkEtv NxsiJQD4U1R8W2nTuJaf4cOouL/5fRYPXNpUNPiYnM3j8J/OqSIF7LkXqcNgD/H3JLfT 7EsODFEXmKAt7WT226E+PNdK87qrwOQeUBBQCP5aXfXBe/67F6AJZsJ/bPq9z/M5Np2p 9XQg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=c67fmHMh; 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 lg23-20020a170906f89700b009769ff4d234si9911496ejb.58.2023.07.26.06.49.29; Wed, 26 Jul 2023 06:49:54 -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=c67fmHMh; 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 S233324AbjGZNAt (ORCPT + 99 others); Wed, 26 Jul 2023 09:00:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233274AbjGZNAn (ORCPT ); Wed, 26 Jul 2023 09:00:43 -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 3D77F1BF2; Wed, 26 Jul 2023 06:00:38 -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 B636361A1D; Wed, 26 Jul 2023 13:00:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 53FFAC433C7; Wed, 26 Jul 2023 13:00:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376437; bh=I2UbfdQQupa3O44BbXXMZ2gOuSLCUPSbCpadML6QpNE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c67fmHMhfFFgzz4Z0AKpQ/iD5zogHsLc+BpXvc0IACsCH+YGlvaq8+viUskz5es6n r8D9vXju6OvBP5EprwypIdTUPX2fyhS5XmAWNe6zsH/MOebVayfH7l5QyDSxsbW06p N7nPbqFv5HTNcTMjyoMI5ha+bbYB7RoiIfcYHXiPisXYS/h2XhLbyAaw3NPh/628Lc HiXsK+W7kcOQLe1tWagXrp2u0VgTkaQdXJVYxDs0EZRYhIX73CzbSARMq2USiwjKZn XHH6vam8GjyEj4qAgrvXp6VrTwgEDTQnBJiPrtFL/yDGbqabJLfj6ZhgsdJ5B89KJ7 c/l+P4/8/eLcg== 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 v3 4/9] tracing/probes: Support BTF based data structure field access Date: Wed, 26 Jul 2023 22:00:33 +0900 Message-Id: <169037643304.607919.11862209354374494379.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772491264281898624 X-GMAIL-MSGID: 1772491264281898624 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. --- kernel/trace/trace_probe.c | 226 +++++++++++++++++++++++++++++++++++++++----- kernel/trace/trace_probe.h | 11 ++ 2 files changed, 210 insertions(+), 27 deletions(-) diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 21a228d88ebb..f6b855de4256 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -309,16 +309,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"; @@ -331,7 +329,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: @@ -354,6 +352,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 */ @@ -405,15 +407,132 @@ 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; + 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; + + field = btf_find_struct_member(ctx->btf, type, fieldname); + if (!field) { + trace_probe_log_err(ctx->offset, NO_BTF_FIELD); + return -ENOENT; + } + + /* 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, @@ -435,24 +554,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); } @@ -461,14 +595,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); } } @@ -476,6 +612,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; @@ -502,14 +660,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) \ @@ -777,6 +943,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 */ @@ -800,7 +968,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; } } @@ -946,6 +1114,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) @@ -953,9 +1122,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); } @@ -1030,6 +1199,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 Wed Jul 26 13:00:42 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: 126381 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp414676vqo; Wed, 26 Jul 2023 06:47:48 -0700 (PDT) X-Google-Smtp-Source: APBJJlEwiKTN0/WdJzJ3qtPnJJA5nUTHWsPPV3bKGjF6emBRya4gRgtB/dLv41JwOvtLLbNTls7D X-Received: by 2002:a05:6402:6d6:b0:515:1e50:5498 with SMTP id n22-20020a05640206d600b005151e505498mr1604085edy.15.1690379267988; Wed, 26 Jul 2023 06:47:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690379267; cv=none; d=google.com; s=arc-20160816; b=SCrazdZxXjP9xJ9J1f3cf+x2WvACrz3r0NTjirjP0JWffoAJfdG2Doa5LxcrD6ot6f 9tc4XwFcp47hTZLfytcYPkZEG8/2ucXTzJDhNt+iUb4zElHz6Xa1xWDa6KXCuf6j+MbK gIJCBEfO1xBY5iWgRU3GUuX/sFaBxqvbU+5oJ+OttKG3NOKiqy0NiXcobn4e55EgUXvv bQyeaTdFKWDlAuKuqwBgYEcCS9lo3aALQSzcrmh/Z2E3+fhm89VXLo5eFuezkLRtqmjY w2CvyJnjdwiV8p1sQbZX+rbZBeze2g6ai6TbOqyUHLAKj72gHbCTGSJ0ABP5c6z95eD/ TVsg== 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=PW0q0eXSf2twh7CLnf74Cq2sv5QF55iO5zuctcXcHFI=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=PlnbaVd5nPjIjfSXUZKM/+vv0rrRbSqgXu/pUGEtNR2pzzpT8lAICiw2ALoJyYvgoX Xf/b1JaGdA3osj2k58X8d9IdluDRxpWYkVknzt8hpB7tszh+vnWSLK/D6gTzNMRMxvp7 t3/hlFY7rMCGsRd8kIlsNplg7VJlsDZYOTCMTDVm8vHQxkNr7bXDoqQzSpdwpcjcTogV Y89TSItwEsibXHviFoxg9OIbJnyRkLx4J6/TEg6qf2bA75oPcWvFLdtAChB8Pf3VgcHn 8CxILn5Dd14YgaVaudoX73OY+EPqjgl4zIEqSeJUnAjOuZ++H1OzLkOu+kKmeUSmtPqM s+XQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=fucDkV3i; 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 d28-20020a056402517c00b0052228551730si5489725ede.279.2023.07.26.06.47.23; Wed, 26 Jul 2023 06:47:47 -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=fucDkV3i; 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 S233315AbjGZNBC (ORCPT + 99 others); Wed, 26 Jul 2023 09:01:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233274AbjGZNBA (ORCPT ); Wed, 26 Jul 2023 09:01:00 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1267A2D44; Wed, 26 Jul 2023 06:00:48 -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 6426E617A5; Wed, 26 Jul 2023 13:00:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 15FF8C433C9; Wed, 26 Jul 2023 13:00:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376446; bh=6/a1q67iDYOczfgPLObhEGtGovnFdh2gQ07B23aoJXA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fucDkV3i/JZtWbxYYMVvij7YNSItWmXdXkG/Ug+28BV5MCTJfAeMRLM07GRacfn2I 4HYuElLW84b7l83hlUyuvFgZPNvDDIGWxHZWvtH5/yRtWyrVwg614qj2uZpFqM3oqF OsvCk47p2xKeDSBgfbt4oGAuyfOb7hGedCDNNr/eBaclLOZOxtvWRz6dJt0VU1kfkN J9b6vHnxyVAbzVpE5cZEwVTGihxWlnMQEF2+IiPmgMIZET/1AtsJxTSgRpmZHrlwK+ afzdfcubLrO/y7F8SLK2CCxfAuui8EcGYVba8StnMhsJUeBvg2jRkMGFAlmp9ioZxq QbskmxB+Wx+fQ== 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 v3 5/9] tracing/probes: Support BTF field access from $retval Date: Wed, 26 Jul 2023 22:00:42 +0900 Message-Id: <169037644255.607919.6218637643155663128.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772491131126238075 X-GMAIL-MSGID: 1772491131126238075 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. --- kernel/trace/trace_probe.c | 180 +++++++++++++++++++------------------------- kernel/trace/trace_probe.h | 1 2 files changed, 80 insertions(+), 101 deletions(-) diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index f6b855de4256..65273fe76a9e 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -363,38 +363,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) @@ -402,6 +410,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; } @@ -517,7 +526,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)) @@ -533,17 +542,32 @@ 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; + } + /* 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; + } else + tid = 0; + code->op = FETCH_OP_RETVAL; + goto found; + } + + 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); @@ -554,7 +578,6 @@ static int parse_btf_arg(char *varname, code->param = i + 1; else code->param = i; - tid = params[i].type; goto found; } @@ -579,7 +602,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; @@ -591,27 +614,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) { @@ -634,28 +636,13 @@ 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); } @@ -675,24 +662,23 @@ static int parse_btf_bitfield(struct fetch_insn **pcode, return -EOPNOTSUPP; } -#define parse_btf_arg_type(ctx) \ +#define find_fetch_type_from_btf_type(ctx) \ find_fetch_type(NULL, ctx->flags) -#define parse_btf_retval_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; @@ -711,18 +697,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"); @@ -824,7 +809,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 */ @@ -1121,12 +1106,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 */ @@ -1415,7 +1397,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) @@ -1426,9 +1407,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); @@ -1437,8 +1417,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; @@ -1453,7 +1431,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 Wed Jul 26 13:00:52 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: 126369 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp411556vqo; Wed, 26 Jul 2023 06:42:33 -0700 (PDT) X-Google-Smtp-Source: APBJJlFYKGLdYZb1GRRYDZb19ccskd7Mk5ECQJQ5ZJU6XZ5eyjUqy9oEgyuME71YZs7oK/XfoSsx X-Received: by 2002:a05:6358:724a:b0:134:df5e:4776 with SMTP id i10-20020a056358724a00b00134df5e4776mr2786416rwa.24.1690378952510; Wed, 26 Jul 2023 06:42:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690378952; cv=none; d=google.com; s=arc-20160816; b=ACtq8xleJgPkwS+RXGg/M02wn7J2oQ+Gr9sfT/9GvD6n3CUnF6nvZUUU0Pt0v0JGL4 NoC5jHuy9xK+TjYgXDatPuukyxMLh+BRcfgX+PIDtk3o2zAmrOyXMjf2/UTig6ruJP/x 1M3It+3mHyPOfnVOV6PRkcCqxDP8OX3zQjRZYTHyizlITjfdaqFBBNMx3cYutedHf54I N39xIzy9KfJSq1S6Kc4fNZBuVQwQ4z/SpF4QHg9hDKWBY9G04011fRtdMhvgbfTZ3g4e io7DcSGm5ClBsGJSwOCHPBSmus5r1g5JlY4bqU4KGcjrlSyMACHjZDrgnY20ud1JTLwx 50hQ== 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=ulhp/vyPMRR1b9TnMI9V0n/t6A/gBwRTSRwq1JyEwzs=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=AvnmO5tE43jYFpZenG7J54kgfcOd95zPF9SMLkOHboW4CkFBIiRFG7/r62tQrqyEXf Hug8njkSUlqfd8Pyq3sj3pibGY98hLVQYRZit4HvDNsoXiJ980ttDK96OPNlRCMGA/Ya nW8Y8f6DTof8rYrHscTqQc8xtnlsIIfO0v7JnxjUAmVYIvOx4m45YaVef0p12/9q7yZs 0oZDbx4qFhJ3hc4Q4V6EjxZm3AqlZOerK9jOxUQjMEjisyLf9tEicIDI7vyZSW28P7Rg njYE6InQnMT+LXyfR21lU5XE86wL2wAyB2+wQCk1RLvwhEojLMXLdkN+GhbNqpWTUoTC T3kA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=loCUU+aa; 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 i127-20020a639d85000000b0055c875d784dsi1004940pgd.374.2023.07.26.06.42.18; Wed, 26 Jul 2023 06:42:32 -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=loCUU+aa; 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 S233306AbjGZNBU (ORCPT + 99 others); Wed, 26 Jul 2023 09:01:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232173AbjGZNBO (ORCPT ); Wed, 26 Jul 2023 09:01:14 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C8BF2681; Wed, 26 Jul 2023 06:00: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 EFCC56068E; Wed, 26 Jul 2023 13:00:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 78DB6C433C7; Wed, 26 Jul 2023 13:00:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376456; bh=5xn7r6yeELI05L0FVp5FQnwWOM0qeKUD3zRDu7nxK2I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=loCUU+aaXcrjN5tanPL1crn8cpmz7bluewnTQG5HbpJpzHFzbw80RmJWUhgghiQC5 zFbTYH2xC5OtdWsE0uBQaxVK921ArsPxN9bn2Mdyg5+i0yK83HGz8WTBgByUqHHmG9 MXlkhY7vtYaXw0H9PxXpzgILa1if/zxbXj63fzhoQgR/sERGRehnvCZq390ffahS0g b1DsjLeaH8RCcT0NunNIXbLUuF3GbK4DOSNeMkNYNNzyeaIz0R2xvJOn/lOMVNLNfq MC8Pc0gkzSTyzOSklZazB4WHsa1PMagbxRXTPOaDGEKA4TEekMKurti0eGTqiuBVlZ U48qKUWQXUEbA== 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 v3 6/9] tracing/probes: Add string type check with BTF Date: Wed, 26 Jul 2023 22:00:52 +0900 Message-Id: <169037645210.607919.8694905190029680811.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772490800310681240 X-GMAIL-MSGID: 1772490800310681240 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 65273fe76a9e..edd234e5b929 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -309,6 +309,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) @@ -665,6 +736,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)) @@ -1107,8 +1185,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 Wed Jul 26 13:01:01 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: 126355 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp402868vqo; Wed, 26 Jul 2023 06:28:05 -0700 (PDT) X-Google-Smtp-Source: APBJJlEdy7MfRXKjXLcIoHzk+28L+BqefrgU7VIYkfmXvH9xw5M/D9F9t7pjpEcV9/bXyQXBDM4r X-Received: by 2002:a19:644a:0:b0:4fe:a5c:efa3 with SMTP id b10-20020a19644a000000b004fe0a5cefa3mr1558423lfj.62.1690378085071; Wed, 26 Jul 2023 06:28:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690378085; cv=none; d=google.com; s=arc-20160816; b=EHZYOLzBTic8v1b64tfsHRM6LF9YVGU24sKDCAOzYNOfDhUoe+vjyTMYgyxeWRo7gX KnIzSA5sSbk+3euRN4NqtbHJ0OeaSDmlu+ZlIKbSbZ+fzt+P0MFah6YnJnNs0Fod97te eM2EffSI3ewL0OKEK13m0fWfeseMypQd2a3ZosE4I90IKYZxyXgpy9Z8BDkVYiZrFNZp re8agAzTvOIxtnUs2mV042u1H1OBIZCJkEZX9SEcuqBb3BTut6LHawcfkCRQWG4sXI3p oEXKRAh/tSdeXtUD3sXpfQg54+3h+dfu50R7oAh6WlrwcIqr4DyyEc9U7LPD//Mif+rX wsxQ== 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=CYLtu2atnVZd21MiiTJJdvw6ssQvwwRszP//CgU2zAgCyLWG+d54bNY2wiCqK9ozbP 8cQjYL0RcrHQ7l7/+C6bQOIR/2Qm/3ooBfiErZS8H4ASOPKaRVIgXdBFEt/dE2HbBRKD SqROF7iGSuCWxeitxtRXcm4nTYG4U0qIbjfSbPzyjHrzDwPuE4e0ODqwlPOUFZ7tBFwl x3ePGmMl/JudOoUP4Yed4W+HVOLGZuhtKbkPjJVJVThqp2OCL17nAxlUxgDnn8y7tp1k 3lJ7umyENWtKecSN3FT81uH546EBS2TU6SIKFKBbEWU5VWYB8egVDdfGmIAo2+uXVN6m rrsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=K36bqciP; 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 d26-20020a170906041a00b009871456e3cdsi9644668eja.439.2023.07.26.06.27.40; Wed, 26 Jul 2023 06:28:05 -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=K36bqciP; 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 S233653AbjGZNB0 (ORCPT + 99 others); Wed, 26 Jul 2023 09:01:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233325AbjGZNBV (ORCPT ); Wed, 26 Jul 2023 09:01:21 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F16F52D79; Wed, 26 Jul 2023 06:01:06 -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 8A09A617A7; Wed, 26 Jul 2023 13:01:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1DB2DC433C7; Wed, 26 Jul 2023 13:01:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376466; bh=gcAsXcNpHr2neQoiFwF9exmEBvK8RQO7NJB0uoPDuFA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K36bqciPpGfZqDLISnjK8YpjO3u9WX+y4Q2K2wfIHLNHdo7BJ6AWECehxAoGz+Vwb HaeRETXihrtizo48sWTenh/8lRhOWSrKzYXiunoqBqwnT3S9zn763/fnGrIiLU0HFw RPgSSqsTwbliIdO9ovmXY60DcWg24ojpOZRQhu8aGn7hdZ5OeGkkBUb6F+SPBUQ5Xw nbpGCLhVykyo954j9hVNBWaE9tVy20h51SGpcAhIfAdRn0cuQ1YjXi2p1AdUEpnLIw NlG0nR7kBDHrAlZTRofsGG/fjfwVtDuJgi+JLmOFI7VQundl/Z3IQ2cf3xnNi1FWuj 3EzsxKruCDT4Q== 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 v3 7/9] tracing/fprobe-event: Assume fprobe is a return event by $retval Date: Wed, 26 Jul 2023 22:01:01 +0900 Message-Id: <169037646179.607919.1122940594695749798.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772489890999862759 X-GMAIL-MSGID: 1772489890999862759 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 Wed Jul 26 13:01:11 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: 126383 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp415240vqo; Wed, 26 Jul 2023 06:48:40 -0700 (PDT) X-Google-Smtp-Source: APBJJlFlui7OYQolWHEw6aGb+ZlGSgztb1hHoEMiOZ49qr3N3tMRt8isouRMRryM/j8845H8H+Vk X-Received: by 2002:a17:907:7808:b0:994:56db:cb8d with SMTP id la8-20020a170907780800b0099456dbcb8dmr1684749ejc.14.1690379320442; Wed, 26 Jul 2023 06:48:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690379320; cv=none; d=google.com; s=arc-20160816; b=zsZO2VF0RdwbpWb0kJdIbSnD5jM7zNk5A1+swesvFQmPbvUoxm1OmjMWGqQ9u2DNPP vlOWiF4Yke4AHIarxrAI+yQOpxVAKq5xo2YBb7/PBeedCI145MpC/R5g4r2z78pKBn8i 5TGnFv9ImkAnu63fidCsMMvW1xzHJjFcwdBUlrAyf/pbWH2MEJFjON28o2ryekyGaMoB U5y4Y1FW72wuwMQ/5R87mbVRwSccJF2tBGI0vgPYWP2JPobzAv/WNUDzM54ndRkwZ6nw fNLbXtdLRtI5+eDbN1LCj1MsoBr9hclexqxUcQEU07bDLbFNN3BHXTcqaxrbigByfLzu ItDA== 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=xxRs3BjVlLT/9+COVbQzeVags52U/8tzEQAcUJrjoSc=; fh=raxTTJvC+dSJYbgfX5JG5gvrVjxTZXczN0HF8iDayLY=; b=qLQJlutN9XLEOnH//3rYhl6ym8eEMpD8+C/NL28gPy8YiqR2+/V8VmbaWC2jhZWuyX kF6ejjCoy7l/IF35DRtyvGduzoAscbEDFx/MrVZAbMQJslGvUHs8GE/dd0OcmUT7hyhZ HSZ4X7CANBFbNrZ0+x6S9VqX1fbKu2/0DFdZUrqF4Pxs7asDEAT9pLTTbLYXXclCh0hg jP1gnm7xyiaq832OV4AtWBkR+4oOTK5hWAWhXs4KKpdp5IB/4PYqnF9K2LJV0HcMTYXj AV8RjPHnTVrOXkWpEw9V2nn+/NaeEwBEjj4d1ChidHJPB13x8+cDMuJyU4RMwjajXGSI EZjg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hLtG+6zV; 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 s16-20020a170906c31000b00991f4e7f49asi9001749ejz.215.2023.07.26.06.48.15; Wed, 26 Jul 2023 06:48:40 -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=hLtG+6zV; 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 S233751AbjGZNBp (ORCPT + 99 others); Wed, 26 Jul 2023 09:01:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233726AbjGZNBa (ORCPT ); Wed, 26 Jul 2023 09:01:30 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B9E112689; Wed, 26 Jul 2023 06:01:16 -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 4E3B6617A0; Wed, 26 Jul 2023 13:01:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CEBF4C433C8; Wed, 26 Jul 2023 13:01:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376475; bh=KGJEEq13A9go4Yhd3XiG1sdw1r30ps972RCgI6Rs1/c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hLtG+6zVJFvWeSUaYKZadVKdntgfcrrog6jSXxIKWqkPk1S2ukerb1CcomtuIQNb3 gmLsCCtW9lpiMpW/7SzbkVeVGmjVdECwlXNriH7acx8jplPEK3BzEBGynJaLJWxcUZ +euWgPGhCflOdMl5sxqXbeTrWfJ/hHM2O/l57ELU60f9yqazpOsYXNj852RrDPlXMJ fwm9KRMFe6pulQmqOscoFh1WOqa5LOkLWfiSg9z7ta0yaqlVxne414OXI8tME66quK 5Wx0re1TKdRgJpkgFqbxpqlcqQFhr14K2LD84kPoGx64Z6I5CQFTZY/rNsEL/sVoEt 9bh2KAH2bAeKQ== 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 v3 8/9] selftests/ftrace: Add BTF fields access testcases Date: Wed, 26 Jul 2023 22:01:11 +0900 Message-Id: <169037647132.607919.15889838982085210322.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772491186427151580 X-GMAIL-MSGID: 1772491186427151580 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. --- .../ftrace/test.d/dynevent/add_remove_btfarg.tc | 14 ++++++++++++++ .../ftrace/test.d/dynevent/fprobe_syntax_errors.tc | 4 ++++ 2 files changed, 18 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..4bfd2f45db42 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 @@ -21,6 +21,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 +36,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 +49,16 @@ fi echo > dynamic_events +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 + 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..49758f77c923 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,10 @@ 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 +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 else check_error 'f vfs_read ^$arg*' # NOSUP_BTFARG check_error 't kfree ^$arg*' # NOSUP_BTFARG From patchwork Wed Jul 26 13:01:21 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: 126351 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp396033vqo; Wed, 26 Jul 2023 06:16:56 -0700 (PDT) X-Google-Smtp-Source: APBJJlEOBf2FfW59WykqRK2d8iXD3KF7ZCtV+4Qm0dF6zowk4j2OVmQ6qeYoPm1zR4DvSzB9tk90 X-Received: by 2002:a05:6512:3c8d:b0:4fd:d016:c2e8 with SMTP id h13-20020a0565123c8d00b004fdd016c2e8mr1923153lfv.43.1690377414145; Wed, 26 Jul 2023 06:16:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690377414; cv=none; d=google.com; s=arc-20160816; b=RKSztZlueO7hcqO9sQwxGhRJB4YdBRo7KgEtuyZBWuzDs7x387qJovgZCaEJ3hrALU vQIjclwAFy8Jo3LWkNvsInOgylN4oxLeEfRzJrMVu4EK9uSYomynjh3dn4DP48qjfu2B 2VbzIQqxXQxnRcodU+UWEQS1Z8SY9SO/nzTpD6t15jn7FK4I/lV/GouBO7aO8yAQFR5v LdMlZu4r/U9FlfxIrbMzJB49beC4RY+Ywr1xbIaYs6o0vYP2ju7i1S2RDQjFfFPDaBUR fM+3EPCvEhYd3TPXUWrSBl4TDjbKJ1cRLw4DB2EimlL63KQmGtTfLA51GW28DRXq1VWE 3XIQ== 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=klHxqjqvyS/SA+BP6c8jbcr6htYQ/NWPlncCxqM2d8D6Gf+Hrw3GWZe+nSLAFejFgJ qZB95WmaURERVh48/khuDZvja72KxhTg83OODoiU0SgETFLTkmH9XfIqx9le9DPrPhip ft4D/IErOfOrHCNfYQxclA7J8vodlp6otRGT4q4St4mJeYBmx1l5p/Y1bKrFwZIl/zEZ 4jJ8FnMcHR7bhb8XR8F8WbFrqMcH91FULMkcizonUrVWjvfvdgP+bk5Nmrrbg4qe4Yx3 PIc1QMB86XaZCULS1WE5aSL8dPsypDV2FTF+oCH3IiIAPKGOnzOrr6i6kZS+F3djz1vk 7UoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Pbc+uSu8; 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 v25-20020a056402185900b0051d9246f95csi9606597edy.174.2023.07.26.06.16.27; Wed, 26 Jul 2023 06:16:54 -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=Pbc+uSu8; 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 S233833AbjGZNBt (ORCPT + 99 others); Wed, 26 Jul 2023 09:01:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60084 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233798AbjGZNBf (ORCPT ); Wed, 26 Jul 2023 09:01:35 -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 EE9FD26BD; Wed, 26 Jul 2023 06:01:26 -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 699A26173F; Wed, 26 Jul 2023 13:01:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D76D0C433C8; Wed, 26 Jul 2023 13:01:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690376485; bh=CcGORqTI9ZQHAZplK151N2vLhAMfOhssOSPkNJphVGw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Pbc+uSu8VD3m5STq3XL048/uvTncN+tUJZ6Zhe/8MbtHzpfZS3Vjt1mel+Qq44uv9 T43JoBLDSZaziybKP954o38v0ix4aSQMH9cLXnuRFwgxWvUZQjh1WfrLbUkXodqz4c Hn3Wdwgkpuc6M66PWQ4m4uaHqR/aBNyzNUVwWgk7modCyi8saqnb1/fwcvvBlKgPNA ysBplL4MGi69v6KwrlSDsmdB7AxG4sG9Vm/8UjpdHBCPtA8CipAdxsyD4AqAb82XQe EKcVaZfeKW1i+addyIzssh0iIbScYejmc0mCiZrekGg9MglzIL5QKBzThgxHg+hvoc kCFzUOSAWyXYQ== 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 v3 9/9] Documentation: tracing: Update fprobe event example with BTF field Date: Wed, 26 Jul 2023 22:01:21 +0900 Message-Id: <169037648115.607919.18187565150152698053.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <169037639315.607919.2613476171148037242.stgit@devnote2> References: <169037639315.607919.2613476171148037242.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: 1772489186931629814 X-GMAIL-MSGID: 1772489186931629814 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``.