bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alan Maguire <alan.maguire@oracle.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	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 01/15] bpf: Extend UAPI to support location information
Date: Fri, 17 Oct 2025 09:43:41 +0100	[thread overview]
Message-ID: <f2e1fd61-7d3a-4aa6-9d36-a74987d040fe@oracle.com> (raw)
In-Reply-To: <CAEf4BzZ-0POy7UyFbyN37Y6zx+_2Q0kKR3hrQffq+KW6MOkZ1w@mail.gmail.com>

On 16/10/2025 19:36, Andrii Nakryiko wrote:
> On Wed, Oct 8, 2025 at 10:35 AM Alan Maguire <alan.maguire@oracle.com> wrote:
>>
>> Add BTF_KIND_LOC_PARAM, BTF_KIND_LOC_PROTO and BTF_KIND_LOCSEC
>> to help represent location information for functions.
>>
>> BTF_KIND_LOC_PARAM is used to represent how we retrieve data at a
>> location; either via a register, or register+offset or a
>> constant value.
>>
>> BTF_KIND_LOC_PROTO represents location information about a location
>> with multiple BTF_KIND_LOC_PARAMs.
>>
>> And finally BTF_KIND_LOCSEC is a set of location sites, each
>> of which has
>>
>> - a name (function name)
>> - a function prototype specifying which types are associated
>>   with parameters
>> - a location prototype specifying where to find those parameters
>> - an address offset
>>
>> This can be used to represent
>>
>> - a fully-inlined function
>> - a partially-inlined function where some _LOC_PROTOs represent
>>   inlined sites as above and others have normal _FUNC representations
>> - a function with optimized parameters; again the FUNC_PROTO
>>   represents the original function, with LOC info telling us
>>   where to obtain each parameter (or 0 if the parameter is
>>   unobtainable)
>>
>> Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
>> ---
>>  include/linux/btf.h            |  29 +++++-
>>  include/uapi/linux/btf.h       |  85 ++++++++++++++++-
>>  kernel/bpf/btf.c               | 168 ++++++++++++++++++++++++++++++++-
>>  tools/include/uapi/linux/btf.h |  85 ++++++++++++++++-
>>  4 files changed, 359 insertions(+), 8 deletions(-)
>>
> 
> [...]
> 
>> @@ -78,6 +80,9 @@ enum {
>>         BTF_KIND_DECL_TAG       = 17,   /* Decl Tag */
>>         BTF_KIND_TYPE_TAG       = 18,   /* Type Tag */
>>         BTF_KIND_ENUM64         = 19,   /* Enumeration up to 64-bit values */
>> +       BTF_KIND_LOC_PARAM      = 20,   /* Location parameter information */
>> +       BTF_KIND_LOC_PROTO      = 21,   /* Location prototype for site */
>> +       BTF_KIND_LOCSEC         = 22,   /* Location section */
>>
>>         NR_BTF_KINDS,
>>         BTF_KIND_MAX            = NR_BTF_KINDS - 1,
>> @@ -198,4 +203,78 @@ struct btf_enum64 {
>>         __u32   val_hi32;
>>  };
>>
>> +/* BTF_KIND_LOC_PARAM consists a btf_type specifying a vlen of 0, name_off is 0
> 
> what if we make LOC_PARAM variable-length (i.e., use vlen). We can
> always have a fixed 4 bytes value that will contain an arg size, maybe
> some flags, and an enum representing what kind of location spec it is
> (constant, register, reg-deref, reg+off, reg+off-deref, etc). And then
> depending on that enum we'll know how to interpret those vlen * 4
> bytes. This will give us extensibility to support more complicated
> expressions, when we will be ready to tackle them. Still nicely
> dedupable, though. WDYT?
>

It's a great idea; extensibility is really important here as I hope we
can learn to cover some of the additional location cases we don't
currently. Also we can retire the whole "continue" flag thing for cases
like multi-register representations of structs; we can instead have a
vlen 2 representation with registers in each slot. What's also nice
about that is that it lines up the LOC_PROTO and FUNC_PROTO indices for
parameters so the same index in LOC_PROTO has its type in FUNC_PROTO.

In terms of specifics, I think removing the arg size from the type/size
btf_type field is a good thing as you suggest; having to reinterpret
negative values there is messy. So what about

/* BTF_KIND_LOC_PARAM consists a btf_type specifying a vlen of 0,
name_off and type/size are 0.
 * It is followed by a singular "struct btf_loc_param" and a
vlen-specified set of "struct btf_loc_param_data".
 */

enum {
	BTF_LOC_PARAM_REG_DATA,
	BTF_LOC_PARAM_CONST_DATA,
};

struct btf_loc_param {
	__u8 size;	/* signed size; negative values represent signed
			 * values of the specified size, for example -8
			 * is an 8-byte signed value.
			 */
	__u8 data;	/* interpret struct btf_loc_param_data */
	__u16 flags;
};

struct btf_loc_param_data {
        union {
		struct {
                        __u16   reg;            /* register number */
                        __u16   flags;          /* register dereference */
                        __s32   offset;         /* offset from
register-stored address */
                };
                struct {
                        __u32 val_lo32;         /* lo 32 bits of 64-bit
value */
                        __u32 val_hi32;         /* hi 32 bits of 64-bit
value */
                };
        };
};
	
I realize we have flags in two places (loc_param and loc_param_data for
registers); just in case we needed some sort of mix of register value
and register dereference I think that makes sense; haven't seen that in
practice yet though. Let me know if the above is what you have in mind.


>> + * and is followed by a singular "struct btf_loc_param". type/size specifies
>> + * the size of the associated location value.  The size value should be
>> + * cast to a __s32 as negative sizes can be specified; -8 to indicate a signed
>> + * 8 byte value for example.
>> + *
>> + * If kind_flag is 1 the btf_loc is a constant value, otherwise it represents
>> + * a register, possibly dereferencing it with the specified offset.
>> + *
>> + * "struct btf_type" is followed by a "struct btf_loc_param" which consists
>> + * of either the 64-bit value or the register number, offset etc.
>> + * Interpretation depends on whether the kind_flag is set as described above.
>> + */
>> +
>> +/* BTF_KIND_LOC_PARAM specifies a signed size; negative values represent signed
>> + * values of the specific size, for example -8 is an 8-byte signed value.
>> + */
>> +#define BTF_TYPE_LOC_PARAM_SIZE(t)     ((__s32)((t)->size))
>> +
>> +/* location param specified by reg + offset is a dereference */
>> +#define BTF_LOC_FLAG_REG_DEREF         0x1
>> +/* next location param is needed to specify parameter location also; for example
>> + * when two registers are used to store a 16-byte struct by value.
>> + */
>> +#define BTF_LOC_FLAG_CONTINUE          0x2
>> +
>> +struct btf_loc_param {
>> +       union {
>> +               struct {
>> +                       __u16   reg;            /* register number */
>> +                       __u16   flags;          /* register dereference */
>> +                       __s32   offset;         /* offset from register-stored address */
>> +               };
>> +               struct {
>> +                       __u32 val_lo32;         /* lo 32 bits of 64-bit value */
>> +                       __u32 val_hi32;         /* hi 32 bits of 64-bit value */
>> +               };
>> +       };
>> +};
>> +
>> +/* BTF_KIND_LOC_PROTO specifies location prototypes; i.e. how locations relate
>> + * to parameters; a struct btf_type of BTF_KIND_LOC_PROTO is followed by a
>> + * a vlen-specified number of __u32 which specify the associated
>> + * BTF_KIND_LOC_PARAM for each function parameter associated with the
>> + * location.  The type should either be 0 (no location info) or point at
>> + * a BTF_KIND_LOC_PARAM.  Multiple BTF_KIND_LOC_PARAMs can be used to
>> + * represent a single function parameter; in such a case each should specify
>> + * BTF_LOC_FLAG_CONTINUE.
>> + *
>> + * The type field in the associated "struct btf_type" should point at an
>> + * associated BTF_KIND_FUNC_PROTO.
>> + */
>> +
>> +/* BTF_KIND_LOCSEC consists of vlen-specified number of "struct btf_loc"
>> + * containing location site-specific information;
>> + *
>> + * - name associated with the location (name_off)
>> + * - function prototype type id (func_proto)
>> + * - location prototype type id (loc_proto)
>> + * - address offset (offset)
>> + */
>> +
>> +struct btf_loc {
>> +       __u32 name_off;
>> +       __u32 func_proto;
>> +       __u32 loc_proto;
>> +       __u32 offset;
>> +};
> 
> What is that offset relative to? Offset within the function in which
> we were inlined? Do we know what that function is? I might have missed
> how we represent that.

The offset is relative to kernel base address (at compile-time the
address of .text, at runtime the address of _start). The reasoning is we
have to deal with kASLR which means any compile-time absolute address
will likely change when the kernel is loaded. So we cannot deal in raw
addresses, and to fixup the addresses we then gather kernel/module base
address at runtime to compute the actual location of the inline site.
See get_base_addr() in tools/lib/bpf/loc.c in patch 14 for an example of
how this is done.

Given this, it might make sense to have a convention where the LOCSEC
specifies the section name also, something like

"inline.text"

What do you think?

> 
>> +
>> +/* helps libbpf know that location declarations are present; libbpf
>> + * can then work around absence if this value is not set.
>> + */
>> +#define BTF_KIND_LOC_UAPI_DEFINED 1
>> +
> 
> you don't mention that in the commit, I'll have to figure this out
> from subsequent patches, but it would be nice to give an overview of
> the purpose of this in this patch
>

This is a bit ugly, but is intended to help deal with the situation -
which happens a lot with distros where we might want to build libbpf
without latest UAPI headers (some distros may not get new UAPI headers
for a while). The libbpf patches check if the above is defined, and if
not supply their own location-related definitions. If in turn libbpf
needs to define them, it defines BTF_KIND_LOC_LIBBPF_DEFINED. Finally
pahole - which needs to compile both with a checkpointed libbpf commit
and a libbpf that may be older and not have location definitions -
checks for either, and if not present does a similar set of declarations
to ensure compilation still succeeds. We use weak declarations of libbpf
location-related functions locally to check if they are available at
runtime; this dynamically determines if the inline feature is available.

Not pretty, but it will help avioid some of the issues we had with BTF
enum64 and compilation.

Thanks!

Alan

  reply	other threads:[~2025-10-17  8:44 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 [this message]
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
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=f2e1fd61-7d3a-4aa6-9d36-a74987d040fe@oracle.com \
    --to=alan.maguire@oracle.com \
    --cc=acme@kernel.org \
    --cc=andrii.nakryiko@gmail.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).