Re: [PATCH bpf-next 1/2] libbpf: implement bpf_usdt_arg_size BPF function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2/24/25 2:05 PM, Andrii Nakryiko wrote:
> On Thu, Feb 20, 2025 at 1:59 PM Ihor Solodrai <ihor.solodrai@xxxxxxxxx> wrote:
>>
>> Information about USDT argument size is implicitly stored in
>> __bpf_usdt_arg_spec, but currently it's not accessbile to BPF programs
>> that use USDT.
>>
>> Implement bpf_sdt_arg_size() that returns the size of an USDT argument
>> in bytes.
>>
>> Factor out __bpf_usdt_arg_spec() routine from bpf_usdt_arg(). It
>> searches for arg_spec given ctx and arg_num.
>>
>> Suggested-by: Andrii Nakryiko <andrii@xxxxxxxxxx>
>> Signed-off-by: Ihor Solodrai <ihor.solodrai@xxxxxxxxx>
>> ---
>>  tools/lib/bpf/usdt.bpf.h | 59 ++++++++++++++++++++++++++++++++--------
>>  1 file changed, 47 insertions(+), 12 deletions(-)
>>
>> diff --git a/tools/lib/bpf/usdt.bpf.h b/tools/lib/bpf/usdt.bpf.h
>> index b811f754939f..6041271c5e4e 100644
>> --- a/tools/lib/bpf/usdt.bpf.h
>> +++ b/tools/lib/bpf/usdt.bpf.h
>> @@ -108,19 +108,12 @@ int bpf_usdt_arg_cnt(struct pt_regs *ctx)
>>         return spec->arg_cnt;
>>  }
>>
>> -/* Fetch USDT argument #*arg_num* (zero-indexed) and put its value into *res.
>> - * Returns 0 on success; negative error, otherwise.
>> - * On error *res is guaranteed to be set to zero.
>> - */
>> -__weak __hidden
>> -int bpf_usdt_arg(struct pt_regs *ctx, __u64 arg_num, long *res)
>> +/* Validate ctx and arg_num, if ok set arg_spec pointer */
>> +static __always_inline
>> +int __bpf_usdt_arg_spec(struct pt_regs *ctx, __u64 arg_num, struct __bpf_usdt_arg_spec **arg_spec)
>>  {
>>         struct __bpf_usdt_spec *spec;
>> -       struct __bpf_usdt_arg_spec *arg_spec;
>> -       unsigned long val;
>> -       int err, spec_id;
>> -
>> -       *res = 0;
>> +       int spec_id;
>>
>>         spec_id = __bpf_usdt_spec_id(ctx);
>>         if (spec_id < 0)
>> @@ -136,7 +129,49 @@ int bpf_usdt_arg(struct pt_regs *ctx, __u64 arg_num, long *res)
>>         if (arg_num >= spec->arg_cnt)
>>                 return -ENOENT;
>>
>> -       arg_spec = &spec->args[arg_num];
>> +       *arg_spec = &spec->args[arg_num];
>> +
>> +       return 0;
>> +}
>> +
>> +/* Returns the size in bytes of the #*arg_num* (zero-indexed) USDT argument.
>> + * Returns negative error if argument is not found or arg_num is invalid.
>> + */
>> +static __always_inline
>> +int bpf_usdt_arg_size(struct pt_regs *ctx, __u64 arg_num)
>> +{
>> +       struct __bpf_usdt_arg_spec *arg_spec;
>> +       int err;
>> +
>> +       err = __bpf_usdt_arg_spec(ctx, arg_num, &arg_spec);
>
> let's not extract this into a separate function. I don't particularly
> like the out parameter, and no need to add another function that could
> be used by users. There isn't much duplication, I think it's fine if
> we just copy/paste few lines of code.

Ok. I wasn't sure what is the tolerance level for copy-pasting in this
context.

>
> pw-bot: cr
>
>> +       if (err)
>> +               return err;
>> +
>> +       /* arg_spec->arg_bitshift = 64 - arg_sz * 8
>> +        * so: arg_sz = (64 - arg_spec->arg_bitshift) / 8
>> +        * Do a bitshift instead of a division to avoid
>> +        * "unsupported signed division" error.
>> +        */
>> +       return (64 - arg_spec->arg_bitshift) >> 3;
>
> arg_bitshift is stored as char (which could be signed), so that's why
> you were getting signed division, just cast to unsigned and keep
> division:
>
> return (64 - (unsigned)arg_spec->arg_bitshift) / 8;

I haven't realized that. Thanks.

>
>> +}
>> +
>> +/* Fetch USDT argument #*arg_num* (zero-indexed) and put its value into *res.
>> + * Returns 0 on success; negative error, otherwise.
>> + * On error *res is guaranteed to be set to zero.
>> + */
>> +__weak __hidden
>> +int bpf_usdt_arg(struct pt_regs *ctx, __u64 arg_num, long *res)
>> +{
>> +       struct __bpf_usdt_arg_spec *arg_spec;
>> +       unsigned long val;
>> +       int err;
>> +
>> +       *res = 0;
>> +
>> +       err = __bpf_usdt_arg_spec(ctx, arg_num, &arg_spec);
>> +       if (err)
>> +               return err;
>> +
>>         switch (arg_spec->arg_type) {
>>         case BPF_USDT_ARG_CONST:
>>                 /* Arg is just a constant ("-4@$-9" in USDT arg spec).
>> --
>> 2.48.1
>>





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux