Re: [PATCH v5 3/9] tracing/probes: Add a function to search a member of a struct/union
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Date: 2023-08-22 14:36:37
Also in:
bpf, lkml
On Tue, 22 Aug 2023 09:37:20 -0400 Steven Rostedt [off-list ref] wrote:
On Mon, 7 Aug 2023 11:54:58 +0900 "Masami Hiramatsu (Google)" [off-list ref] wrote:quoted
--- a/kernel/trace/trace_btf.c +++ b/kernel/trace/trace_btf.c@@ -50,3 +50,60 @@ const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, s3 return NULL; } +#define BTF_ANON_STACK_MAX 16 + +/* + * Find a member of data structure/union by name and return it. + * Return NULL if not found, or -EINVAL if parameter is invalid. + * If the member is an member of anonymous union/structure, the offset + * of that anonymous union/structure is stored into @anon_offset. Caller + * can calculate the correct offset from the root data structure by + * adding anon_offset to the member's offset. + */ +const struct btf_member *btf_find_struct_member(struct btf *btf, + const struct btf_type *type, + const char *member_name, + u32 *anon_offset) +{ + struct { + u32 tid; + u32 offset; + } anon_stack[BTF_ANON_STACK_MAX];Where is this called as the above is 128 bytes, which is a bit large for the stack. It may not be bad if it's not that generic of a function. But if the stack is getting tight, this could still be an issue.
OK, let me allocate an array then. Thank you,
-- Stevequoted
+ const struct btf_member *member; + u32 tid, cur_offset = 0; + const char *name; + int i, top = 0; + +retry: + if (!btf_type_is_struct(type)) + return ERR_PTR(-EINVAL); + + for_each_member(i, type, member) { + if (!member->name_off) { + /* Anonymous union/struct: push it for later use */ + type = btf_type_skip_modifiers(btf, member->type, &tid); + if (type && top < BTF_ANON_STACK_MAX) { + anon_stack[top].tid = tid; + anon_stack[top++].offset = + cur_offset + member->offset; + } + } else { + name = btf_name_by_offset(btf, member->name_off); + if (name && !strcmp(member_name, name)) { + if (anon_offset) + *anon_offset = cur_offset; + return member; + } + } + } + if (top > 0) { + /* Pop from the anonymous stack and retry */ + tid = anon_stack[--top].tid; + cur_offset = anon_stack[top].offset; + type = btf_type_by_id(btf, tid); + goto retry; + } + + return NULL; +} +
-- Masami Hiramatsu (Google) [off-list ref]