Re: [PATCH v2 bpf-next 8/9] libbpf: implement __arg_ctx fallback logic

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

 



On Wed, Jan 3, 2024 at 12:57 PM Eduard Zingerman <eddyz87@xxxxxxxxx> wrote:
>
> On Tue, 2024-01-02 at 11:00 -0800, Andrii Nakryiko wrote:
>
> [...]
>
> > +static int clone_func_btf_info(struct btf *btf, int orig_fn_id, struct bpf_program *prog)
> > +{
>
> [...]
>
> > +     /* clone FUNC first, btf__add_func() enforces
> > +      * non-empty name, so use entry program's name as
> > +      * a placeholder, which we replace immediately
> > +      */
> > +     fn_id = btf__add_func(btf, prog->name, btf_func_linkage(fn_t), fn_t->type);
>
> Nit: Why not call this function near the end, when fn_proto_id is available?
>      Thus avoiding need to "guess" fn_t->type.
>

I think I did it to not have to remember btf_func_linkage(fn_t)
(because fn_t will be invalidated) and because name_off will be reused
for parameters. Neither is a big deal, I'll adjust to your suggestion.

But note, we are not guessing ID, it's guaranteed to be +1, it's an
API contract of btf__add_xxx() APIs.

> [...]
>
> > +static int bpf_program_fixup_func_info(struct bpf_object *obj, struct bpf_program *prog)
> > +{
>
> [...]
>
> > +     for (i = 1, n = btf__type_cnt(btf); i < n; i++) {
>
> [...]
>
> > +
> > +             /* clone fn/fn_proto, unless we already did it for another arg */
> > +             if (func_rec->type_id == orig_fn_id) {
> > +                     int fn_id;
> > +
> > +                     fn_id = clone_func_btf_info(btf, orig_fn_id, prog);
> > +                     if (fn_id < 0) {
> > +                             err = fn_id;
> > +                             goto err_out;
> > +                     }
> > +
> > +                     /* point func_info record to a cloned FUNC type */
> > +                     func_rec->type_id = fn_id;
>
> Would it be helpful to add a log here, saying that BTF for function
> so and so is changed before load?

Would it? We don't have global subprog's name readily available, it
seems. So I'd need to refetch it by fn_id, then btf__str_by_offset()
just to emit cryptic (for most users) notifications that something
about some func info was adjusted. And then the user would get this
same message for the same subprog but in the context of a different
entry program. Just confusing, tbh.

Unless you insist, I'd leave it as is. This logic is supposed to be
bullet-proof, so I'm not worried about debugging regressions with it
(but maybe I'm delusional).

>
> > +             }
> > +
> > +             /* create PTR -> STRUCT type chain to mark PTR_TO_CTX argument;
> > +              * we do it just once per main BPF program, as all global
> > +              * funcs share the same program type, so need only PTR ->
> > +              * STRUCT type chain
> > +              */
> > +             if (ptr_id == 0) {
> > +                     struct_id = btf__add_struct(btf, ctx_name, 0);
>
> Nit: Maybe try looking up existing id for type ctx_name first?

It didn't feel important and I didn't want to do another linear BTF
search for each such argument. It's trivial to look it up, but I still
feel like that's a waste... I tried to avoid many linear searches,
which is why I structured the logic to do one pass over BTF to find
all decl_tags instead of going over each function and arg and
searching for decl_tag.

Let's keep it as is, if there are any reasons to try to reuse struct
(if it is at all present, which for kprobe, for example, is quite
unlikely due to fancy bpf_user_pt_regs_t name), then we can easily add
it with no regressions.

>
> > +                     ptr_id = btf__add_ptr(btf, struct_id);
> > +                     if (ptr_id < 0 || struct_id < 0) {
> > +                             err = -EINVAL;
> > +                             goto err_out;
> > +                     }
> > +             }
> > +
>
> [...]
>
>





[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