From: "Ihor Solodrai" <ihor.solodrai@linux.dev>
To: "Alan Maguire" <alan.maguire@oracle.com>,
dwarves@vger.kernel.org, bpf@vger.kernel.org
Cc: acme@kernel.org, ast@kernel.org, andrii@kernel.org,
eddyz87@gmail.com, mykolal@fb.com, kernel-team@meta.com
Subject: Re: [PATCH dwarves 2/3] btf_encoder: emit type tags for bpf_arena pointers
Date: Tue, 11 Feb 2025 00:11:15 +0000 [thread overview]
Message-ID: <a78e27341fbc150d767589f6dddbf932e91dc41c@linux.dev> (raw)
In-Reply-To: <f2b54a36-cea3-4729-bc5b-8524a5be50fa@oracle.com>
On 2/10/25 2:11 PM, Alan Maguire wrote:
> On 07/02/2025 02:14, Ihor Solodrai wrote:
>> When adding a kfunc prototype to BTF, check for the flags indicating
>> bpf_arena pointers and emit a type tag encoding
>> __attribute__((address_space(1))) for them. This also requires
>> updating BTF type ids in the btf_encoder_func_state, which is done as
>> a side effect in the tagging functions.
>>
>> This feature depends on recent update in libbpf, supporting arbitrarty
>> attribute encoding [1].
>>
>> [1] https://lore.kernel.org/bpf/20250130201239.1429648-1-ihor.solodrai@linux.dev/
>>
>> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
>
> a few minor issues below, but
>
> Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
>
>> ---
>> btf_encoder.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 96 insertions(+), 1 deletion(-)
>>
>> diff --git a/btf_encoder.c b/btf_encoder.c
>> index e9f4baf..d7837c2 100644
>> --- a/btf_encoder.c
>> +++ b/btf_encoder.c
>> @@ -40,7 +40,13 @@
>> #define BTF_SET8_KFUNCS (1 << 0)
>> #define BTF_KFUNC_TYPE_TAG "bpf_kfunc"
>> #define BTF_FASTCALL_TAG "bpf_fastcall"
>> -#define KF_FASTCALL (1 << 12)
>> +#define BPF_ARENA_ATTR "address_space(1)"
>> +
>> +/* kfunc flags, see include/linux/btf.h in the kernel source */
>> +#define KF_FASTCALL (1 << 12)
>> +#define KF_ARENA_RET (1 << 13)
>> +#define KF_ARENA_ARG1 (1 << 14)
>> +#define KF_ARENA_ARG2 (1 << 15)
>>
>> struct btf_id_and_flag {
>> uint32_t id;
>> @@ -743,6 +749,91 @@ static int32_t btf_encoder__tag_type(struct btf_encoder *encoder, uint32_t tag_t
>> return encoder->type_id_off + tag_type;
>> }
>>
>> +static inline struct kfunc_info* btf_encoder__kfunc_by_name(struct btf_encoder *encoder, const char *name) {
>> + struct kfunc_info *kfunc;
>> +
>> + list_for_each_entry(kfunc, &encoder->kfuncs, node) {
>> + if (strcmp(kfunc->name, name) == 0)
>> + return kfunc;
>> + }
>> + return NULL;
>> +}
>> +
>
> above function is only used within #if statement below, right? Should
> probably move it there to avoid warnings.
Right. I think some of these functions may go away, given Eduard's
suggestions.
>
>> +#if LIBBPF_MAJOR_VERSION >= 1 && LIBBPF_MINOR_VERSION >= 6
>> +static int btf_encoder__tag_bpf_arena_ptr(struct btf *btf, int ptr_id)
>> +{
>> + const struct btf_type *ptr;
>> + int tagged_type_id;
>> +
>> + ptr = btf__type_by_id(btf, ptr_id);
>> + if (!btf_is_ptr(ptr))
>> + return -EINVAL;
>> +
>> + tagged_type_id = btf__add_type_attr(btf, BPF_ARENA_ATTR, ptr->type);
>> + if (tagged_type_id < 0)
>> + return tagged_type_id;
>> +
>> + return btf__add_ptr(btf, tagged_type_id);
>> +}
>> +
>> +static int btf_encoder__tag_bpf_arena_arg(struct btf *btf, struct btf_encoder_func_state *state, int idx)
>> +{
>> + int id;
>> +
>> + if (state->nr_parms <= idx)
>> + return -EINVAL;
>> +
>> + id = btf_encoder__tag_bpf_arena_ptr(btf, state->parms[idx].type_id);
>> + if (id < 0) {
>> + btf__log_err(btf, BTF_KIND_TYPE_TAG, BPF_ARENA_ATTR, true, id,
>> + "Error adding BPF_ARENA_ATTR for an argument of kfunc '%s'", state->elf->name);
>
> nit: since we call this for arguments + return value, should we reflect
> that in the function name/error message? maybe pass in the KF_ARENA_*
> flag or something?
It is what's happening. btf_encoder__tag_bpf_arena_ptr is called from
btf_encoder__tag_bpf_arena_arg and separately for a return type:
if (KF_ARENA_RET & kfunc->flags) {
ret_type_id = btf_encoder__tag_bpf_arena_ptr(encoder->btf, state->ret_type_id);
In both cases the return value is checked and the error message is
different.
I factored out *_arg version of this operation because it has to be
done twice: for _ARG1 and _ARG2.
Maybe I misunderstood you question? lmk
>
>> + return id;
>> + }
>> + state->parms[idx].type_id = id;
>> +
>> + return id;
>> +}
>> +
>> +static int btf_encoder__add_bpf_arena_type_tags(struct btf_encoder *encoder, struct btf_encoder_func_state *state)
>> +{
>> + struct kfunc_info *kfunc = NULL;
>> + int ret_type_id;
>> + int err = 0;
>> +
>> + if (!state || !state->elf || !state->elf->kfunc)
>> + goto out;
>> +
>> + kfunc = btf_encoder__kfunc_by_name(encoder, state->elf->name);
>> + if (!kfunc)
>> + goto out;
>> +
>> + if (KF_ARENA_RET & kfunc->flags) {
>> + ret_type_id = btf_encoder__tag_bpf_arena_ptr(encoder->btf, state->ret_type_id);
>> + if (ret_type_id < 0) {
>> + btf__log_err(encoder->btf, BTF_KIND_TYPE_TAG, BPF_ARENA_ATTR, true, ret_type_id,
>> + "Error adding BPF_ARENA_ATTR for return type of kfunc '%s'", state->elf->name);
>> + err = ret_type_id;
>> + goto out;
>> + }
>> + state->ret_type_id = ret_type_id;
>> + }
>> +
>> + if (KF_ARENA_ARG1 & kfunc->flags) {
>> + err = btf_encoder__tag_bpf_arena_arg(encoder->btf, state, 0);
>> + if (err < 0)
>> + goto out;
>> + }
>> +
>> + if (KF_ARENA_ARG2 & kfunc->flags) {
>> + err = btf_encoder__tag_bpf_arena_arg(encoder->btf, state, 1);
>> + if (err < 0)
>> + goto out;
>> + }
>> +out:
>> + return err;
>
> not sure we need goto outs here; there are no resources to free etc so
> we can just return err/return 0 where appropriate.
ack
>
>> +}
>> +#endif // LIBBPF_MAJOR_VERSION >= 1 && LIBBPF_MINOR_VERSION >= 6
>> +
>> static int32_t btf_encoder__add_func_proto(struct btf_encoder *encoder, struct ftype *ftype,
>> struct btf_encoder_func_state *state)
>> {
>> @@ -762,6 +853,10 @@ static int32_t btf_encoder__add_func_proto(struct btf_encoder *encoder, struct f
>> nr_params = ftype->nr_parms + (ftype->unspec_parms ? 1 : 0);
>> type_id = btf_encoder__tag_type(encoder, ftype->tag.type);
>> } else if (state) {
>> +#if LIBBPF_MAJOR_VERSION >= 1 && LIBBPF_MINOR_VERSION >= 6
>> + if (btf_encoder__add_bpf_arena_type_tags(encoder, state) < 0)
>
> kind of a nit I guess, but I think it might be clearer to make explicit
> the work we only have to do for kfuncs, i.e.
>
> if (state->elf && state->elf->kfunc) {
> /* do kfunc-specific work like arena ptr tag */
>
> }
>
> I know the function has checks for this internally but I think it makes
> it a bit clearer that it's only needed for a small subset of functions,
> what do you think?
Actually I did write it like that first. IIRC tagging has to be done
before `type_id = state->ret_type_id;` and only when `state` is
passed.
Anyways, I agree it should be clearer that this happens just for some
functions.
>
>
>> + return -1;
>> +#endif
>> encoder = state->encoder;
>> btf = state->encoder->btf;
>> nr_params = state->nr_parms;
next prev parent reply other threads:[~2025-02-11 0:11 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-07 2:14 [PATCH dwarves 0/3] btf_encoder: emit type tags for bpf_arena pointers Ihor Solodrai
2025-02-07 2:14 ` [PATCH dwarves 1/3] btf_encoder: collect kfuncs info in btf_encoder__new Ihor Solodrai
2025-02-10 20:57 ` Eduard Zingerman
2025-02-10 22:42 ` Ihor Solodrai
2025-02-11 0:35 ` Eduard Zingerman
2025-02-07 2:14 ` [PATCH dwarves 2/3] btf_encoder: emit type tags for bpf_arena pointers Ihor Solodrai
2025-02-10 22:11 ` Alan Maguire
2025-02-11 0:11 ` Ihor Solodrai [this message]
2025-02-07 2:14 ` [PATCH dwarves 3/3] pahole: introduce --btf_feature=attributes Ihor Solodrai
2025-02-10 22:13 ` Alan Maguire
2025-02-11 0:16 ` Ihor Solodrai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a78e27341fbc150d767589f6dddbf932e91dc41c@linux.dev \
--to=ihor.solodrai@linux.dev \
--cc=acme@kernel.org \
--cc=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=dwarves@vger.kernel.org \
--cc=eddyz87@gmail.com \
--cc=kernel-team@meta.com \
--cc=mykolal@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.