diff options
| author | Masami Hiramatsu (Google) <mhiramat@kernel.org> | 2026-07-02 21:12:41 +0900 |
|---|---|---|
| committer | Masami Hiramatsu (Google) <mhiramat@kernel.org> | 2026-07-14 22:43:16 +0900 |
| commit | 738b78ee4bfa5e290f155be1e946bc2ae5660dfd (patch) | |
| tree | 733aa8a8fbaa4ab8637c9a5b70886c95f2fc3559 /kernel/trace/trace_probe.c | |
| parent | f2183452402508ad68ea01eed18ae8eecfcd8f0a (diff) | |
| download | linux-next-738b78ee4bfa5e290f155be1e946bc2ae5660dfd.tar.gz linux-next-738b78ee4bfa5e290f155be1e946bc2ae5660dfd.zip | |
tracing/probes: Add $current variable support
Since we can use the BTF to cast value to a structure pointer type,
it is useful to introduce "$current" special variable support to
fetcharg.
User can define a fetcharg to access current task_struct properties
using BTF info. e.g.
$current->cpus_ptr
Link: https://lore.kernel.org/all/178271366709.1176915.15320906169981578568.stgit@devnote2/
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Diffstat (limited to 'kernel/trace/trace_probe.c')
| -rw-r--r-- | kernel/trace/trace_probe.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index fd006b415c68..999dec84275d 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -692,7 +692,9 @@ static int parse_btf_arg(char *varname, int i, is_ptr, ret; u32 tid; - if (!ctx->funcname && !(ctx->flags & TPARG_FL_TEVENT)) + /* Note: field is not separated at this point, so check prefix. */ + if (!str_has_prefix(varname, "$current") && + !ctx->funcname && !(ctx->flags & TPARG_FL_TEVENT)) return -EINVAL; is_ptr = split_next_field(varname, &field, ctx); @@ -705,6 +707,20 @@ static int parse_btf_arg(char *varname, return -EOPNOTSUPP; } + if (!strcmp(varname, "$current")) { + code->op = FETCH_OP_CURRENT; + /* If no typecast is specified for $current, use task_struct by default */ + ret = bpf_find_btf_id("task_struct", BTF_KIND_STRUCT, &ctx->struct_btf); + if (ret < 0) { + trace_probe_log_err(ctx->offset, NO_BTF_ENTRY); + return -ENOENT; + } + tid = (u32)ret; + type = ctx->last_struct = + btf_type_skip_modifiers(ctx->struct_btf, tid, NULL); + goto found_type; + } + if (ctx->flags & TPARG_FL_RETURN && !strcmp(varname, "$retval")) { code->op = FETCH_OP_RETVAL; /* Check whether the function return type is not void, even with typecast. */ @@ -761,6 +777,7 @@ static int parse_btf_arg(char *varname, found: type = btf_type_skip_modifiers(ctx->btf, tid, NULL); +found_type: if (!type) { trace_probe_log_err(ctx->offset, BAD_BTF_TID); return -EINVAL; @@ -1270,6 +1287,24 @@ static int parse_probe_vars(char *orig_arg, const struct fetch_type *t, return 0; } + /* $current returns the address of the current task_struct. */ + if (str_has_prefix(arg, "current")) { + /* $current is only supported by kernel probe. */ + if (!(ctx->flags & TPARG_FL_KERNEL)) { + err = TP_ERR_BAD_VAR; + goto inval; + } + arg += strlen("current"); + if (*arg == '-' && IS_ENABLED(CONFIG_PROBE_EVENTS_BTF_ARGS)) + return parse_btf_arg(orig_arg, pcode, end, ctx); + + if (*arg != '\0') + goto inval; + + code->op = FETCH_OP_CURRENT; + return 0; + } + #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API len = str_has_prefix(arg, "arg"); if (len) { |
