From: Eduard Zingerman <eddyz87@gmail.com>
To: Alan Maguire <alan.maguire@oracle.com>,
ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org
Cc: martin.lau@linux.dev, acme@kernel.org, ttreyer@meta.com,
yonghong.song@linux.dev, song@kernel.org,
john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me,
haoluo@google.com, jolsa@kernel.org, qmo@kernel.org,
ihor.solodrai@linux.dev, david.faust@oracle.com,
jose.marchesi@oracle.com, bpf@vger.kernel.org
Subject: Re: [RFC bpf-next 02/15] libbpf: Add support for BTF kinds LOC_PARAM, LOC_PROTO and LOCSEC
Date: Wed, 22 Oct 2025 17:57:32 -0700 [thread overview]
Message-ID: <adb75ea792825e164a4758e40059a677d26694b7.camel@gmail.com> (raw)
In-Reply-To: <20251008173512.731801-3-alan.maguire@oracle.com>
On Wed, 2025-10-08 at 18:34 +0100, Alan Maguire wrote:
[...]
> diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
> index 18907f0fcf9f..0abd7831d6b4 100644
> --- a/tools/lib/bpf/btf.c
> +++ b/tools/lib/bpf/btf.c
[...]
> @@ -588,6 +621,34 @@ static int btf_validate_type(const struct btf *btf, const struct btf_type *t, __
offtopic: we should probably switch this function to use field and string iterators.
> }
> break;
> }
> + case BTF_KIND_LOC_PARAM:
> + break;
> + case BTF_KIND_LOC_PROTO: {
> + __u32 *p = btf_loc_proto_params(t);
> +
> + n = btf_vlen(t);
> + for (i = 0; i < n; i++, p++) {
> + err = btf_validate_id(btf, *p, id);
> + if (err)
> + return err;
> + }
> + break;
> + }
> + case BTF_KIND_LOCSEC: {
> + const struct btf_loc *l = btf_locsec_locs(t);
> +
> + n = btf_vlen(t);
> + for (i = 0; i < n; i++, l++) {
> + err = btf_validate_str(btf, l->name_off, "loc name", id);
> + if (!err)
> + err = btf_validate_id(btf, l->func_proto, id);
> + if (!err)
> + btf_validate_id(btf, l->loc_proto, id);
^^^^
Missing `err =`?
> + if (err)
> + return err;
> + }
> + break;
> + }
> default:
> pr_warn("btf: type [%u]: unrecognized kind %u\n", id, kind);
> return -EINVAL;
> @@ -2993,6 +3054,183 @@ int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id,
> return btf_add_decl_tag(btf, value, ref_type_id, component_idx, 1);
> }
>
> +/*
> + * Append new BTF_KIND_LOC_PARAM with either
> + * - *value* set as __u64 value following btf_type, with info->kflag set to 1
> + * if *is_value* is true; or
> + * - *reg* number, *flags* and *offset* set if *is_value* is set to 0, and
> + * info->kflag set to 0.
> + * Returns:
> + * - >0, type ID of newly added BTF type;
> + * - <0, on error.
> + */
> +int btf__add_loc_param(struct btf *btf, __s32 size, bool is_value, __u64 value,
> + __u16 reg, __u16 flags, __s32 offset)
Probably, would be more convenient to have several functions, e.g.:
- btf__add_loc_param_const()
- btf__add_loc_param_reg()
- btf__add_loc_param_deref()
Should `size` be some kind of enum?
E.g. with values like S64, S32, ..., U64.
So the the usage would be like:
btf__add_loc_param_const(btf, U64, 0xdeadbeef);
Wdyt?
> +{
> + struct btf_loc_param *p;
> + struct btf_type *t;
> + int sz;
> +
> + if (btf_ensure_modifiable(btf))
> + return libbpf_err(-ENOMEM);
> +
> + sz = sizeof(struct btf_type) + sizeof(__u64);
> + t = btf_add_type_mem(btf, sz);
> + if (!t)
> + return libbpf_err(-ENOMEM);
> +
> + t->name_off = 0;
> + t->info = btf_type_info(BTF_KIND_LOC_PARAM, 0, is_value);
> + t->size = size;
> +
> + p = btf_loc_param(t);
> +
> + if (is_value) {
> + p->val_lo32 = value & 0xffffffff;
> + p->val_hi32 = value >> 32;
> + } else {
> + p->reg = reg;
> + p->flags = flags;
> + p->offset = offset;
> + }
> + return btf_commit_type(btf, sz);
> +}
[...]
> +int btf__add_locsec_loc(struct btf *btf, const char *name, __u32 func_proto, __u32 loc_proto,
> + __u32 offset)
> +{
> + struct btf_type *t;
> + struct btf_loc *l;
> + int name_off, sz;
> +
> + if (!name || !name[0])
> + return libbpf_err(-EINVAL);
> +
> + if (validate_type_id(func_proto) || validate_type_id(loc_proto))
> + return libbpf_err(-EINVAL);
> +
> + /* last type should be BTF_KIND_LOCSEC */
> + if (btf->nr_types == 0)
> + return libbpf_err(-EINVAL);
> + t = btf_last_type(btf);
> + if (!btf_is_locsec(t))
> + return libbpf_err(-EINVAL);
> +
> + /* decompose and invalidate raw data */
> + if (btf_ensure_modifiable(btf))
> + return libbpf_err(-ENOMEM);
> +
> + name_off = btf__add_str(btf, name);
> + if (name_off < 0)
> + return name_off;
> +
> + sz = sizeof(*l);
> + l = btf_add_type_mem(btf, sz);
> + if (!l)
> + return libbpf_err(-ENOMEM);
> +
> + l->name_off = name_off;
> + l->func_proto = func_proto;
> + l->loc_proto = loc_proto;
> + l->offset = offset;
> +
> + /* update parent type's vlen */
> + t = btf_last_type(btf);
> + btf_type_inc_vlen(t);
Since vlen is only u16, maybe check for overflow and report an error here?
> +
> + btf->hdr->type_len += sz;
> + btf->hdr->str_off += sz;
> + return 0;
> +}
> +
> struct btf_ext_sec_info_param {
> __u32 off;
> __u32 len;
[...]
> @@ -5075,6 +5361,45 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
> break;
> }
>
> + case BTF_KIND_LOC_PROTO: {
> + __u32 *p1, *p2;
> + __u16 i, vlen;
> +
> + p1 = btf_loc_proto_params(t);
> + vlen = btf_vlen(t);
> +
> + for (i = 0; i < vlen; i++, p1++) {
> + ref_type_id = btf_dedup_ref_type(d, *p1);
> + if (ref_type_id < 0)
> + return ref_type_id;
> + *p1 = ref_type_id;
> + }
> +
> + h = btf_hash_loc_proto(t);
> + for_each_dedup_cand(d, hash_entry, h) {
> + cand_id = hash_entry->value;
> + cand = btf_type_by_id(d->btf, cand_id);
> + if (!btf_equal_common(t, cand))
> + continue;
Nit: having btf_equal_loc_proto() would have been more readable here.
> + vlen = btf_vlen(cand);
> + p1 = btf_loc_proto_params(t);
> + p2 = btf_loc_proto_params(cand);
> + if (vlen == 0) {
> + new_id = cand_id;
> + break;
> + }
> + for (i = 0; i < vlen; i++, p1++, p2++) {
> + if (*p1 != *p2)
> + break;
> + new_id = cand_id;
> + break;
> + }
> + if (new_id == cand_id)
> + break;
Why `break` and not `continue`?
Also, BTF_KIND_FUNC_PROTO does not have this special case, why the difference?
> + }
> + break;
> + }
> +
> default:
> return -EINVAL;
> }
[...]
> diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
> index 6388392f49a0..95bdda2f4a2d 100644
> --- a/tools/lib/bpf/btf_dump.c
> +++ b/tools/lib/bpf/btf_dump.c
> @@ -328,6 +328,9 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
> case BTF_KIND_ENUM64:
> case BTF_KIND_FWD:
> case BTF_KIND_FLOAT:
> + case BTF_KIND_LOC_PARAM:
> + case BTF_KIND_LOC_PROTO:
> + case BTF_KIND_LOCSEC:
> break;
>
> case BTF_KIND_VOLATILE:
> @@ -339,7 +342,6 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
> case BTF_KIND_VAR:
> case BTF_KIND_DECL_TAG:
> case BTF_KIND_TYPE_TAG:
> - d->type_states[t->type].referenced = 1;
> break;
This change seems unrelated, why is it necessary?
>
> case BTF_KIND_ARRAY: {
[...]
next prev parent reply other threads:[~2025-10-23 0:57 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-08 17:34 [RFC bpf-next 00/15] support inline tracing with BTF Alan Maguire
2025-10-08 17:34 ` [RFC bpf-next 01/15] bpf: Extend UAPI to support location information Alan Maguire
2025-10-16 18:36 ` Andrii Nakryiko
2025-10-17 8:43 ` Alan Maguire
2025-10-20 20:57 ` Andrii Nakryiko
2025-10-23 8:17 ` Alan Maguire
2025-11-05 0:43 ` Andrii Nakryiko
2025-10-23 0:56 ` Eduard Zingerman
2025-10-23 8:35 ` Alan Maguire
2025-10-08 17:34 ` [RFC bpf-next 02/15] libbpf: Add support for BTF kinds LOC_PARAM, LOC_PROTO and LOCSEC Alan Maguire
2025-10-23 0:57 ` Eduard Zingerman [this message]
2025-10-23 19:18 ` Eduard Zingerman
2025-10-23 19:59 ` Eduard Zingerman
2025-10-08 17:34 ` [RFC bpf-next 03/15] libbpf: Add option to retrieve map from old->new ids from btf__dedup() Alan Maguire
2025-10-16 18:39 ` Andrii Nakryiko
2025-10-17 8:56 ` Alan Maguire
2025-10-20 21:03 ` Andrii Nakryiko
2025-10-23 8:25 ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 04/15] libbpf: Fix parsing of multi-split BTF Alan Maguire
2025-10-16 18:36 ` Andrii Nakryiko
2025-10-17 13:47 ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 05/15] bpftool: Add ability to dump LOC_PARAM, LOC_PROTO and LOCSEC Alan Maguire
2025-10-23 0:57 ` Eduard Zingerman
2025-10-23 8:38 ` Alan Maguire
2025-10-23 8:50 ` Eduard Zingerman
2025-10-08 17:35 ` [RFC bpf-next 06/15] bpftool: Handle multi-split BTF by supporting multiple base BTFs Alan Maguire
2025-10-16 18:36 ` Andrii Nakryiko
2025-10-17 13:47 ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 07/15] selftests/bpf: Test helper support for BTF_KIND_LOC[_PARAM|_PROTO|SEC] Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 08/15] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to field iter tests Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 09/15] selftests/bpf: Add LOC_PARAM, LOC_PROTO, LOCSEC to dedup split tests Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 10/15] selftests/bpf: BTF distill tests to ensure LOC[_PARAM|_PROTO] add to split BTF Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 11/15] kbuild: Add support for extra BTF Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 12/15] kbuild, module, bpf: Support CONFIG_DEBUG_INFO_BTF_EXTRA=m Alan Maguire
2025-10-16 18:37 ` Andrii Nakryiko
2025-10-17 13:54 ` Alan Maguire
2025-10-20 21:05 ` Andrii Nakryiko
2025-10-23 0:58 ` Eduard Zingerman
2025-10-23 12:00 ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 13/15] libbpf: add API to load extra BTF Alan Maguire
2025-10-16 18:37 ` Andrii Nakryiko
2025-10-17 13:55 ` Alan Maguire
2025-10-08 17:35 ` [RFC bpf-next 14/15] libbpf: add support for BTF location attachment Alan Maguire
2025-10-16 18:36 ` Andrii Nakryiko
2025-10-17 14:02 ` Alan Maguire
2025-10-20 21:07 ` Andrii Nakryiko
2025-10-08 17:35 ` [RFC bpf-next 15/15] selftests/bpf: Add test tracing inline site using SEC("kloc") Alan Maguire
2025-10-12 23:45 ` [RFC bpf-next 00/15] support inline tracing with BTF Alexei Starovoitov
2025-10-13 7:38 ` Alan Maguire
2025-10-14 0:12 ` Alexei Starovoitov
2025-10-14 9:58 ` Alan Maguire
2025-10-16 18:36 ` Andrii Nakryiko
2025-10-23 14:37 ` Alan Maguire
2025-10-23 16:16 ` Andrii Nakryiko
2025-10-24 11:53 ` Alan Maguire
2025-10-14 11:52 ` Jiri Olsa
2025-10-14 14:55 ` Alan Maguire
2025-10-14 23:04 ` Masami Hiramatsu
2025-10-15 14:17 ` Jiri Olsa
2025-10-15 15:19 ` Alan Maguire
2025-10-15 18:35 ` Jiri Olsa
2025-10-23 22:32 ` Eduard Zingerman
2025-10-24 12:54 ` Alan Maguire
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=adb75ea792825e164a4758e40059a677d26694b7.camel@gmail.com \
--to=eddyz87@gmail.com \
--cc=acme@kernel.org \
--cc=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=david.faust@oracle.com \
--cc=haoluo@google.com \
--cc=ihor.solodrai@linux.dev \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=jose.marchesi@oracle.com \
--cc=kpsingh@kernel.org \
--cc=martin.lau@linux.dev \
--cc=qmo@kernel.org \
--cc=sdf@fomichev.me \
--cc=song@kernel.org \
--cc=ttreyer@meta.com \
--cc=yonghong.song@linux.dev \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).