All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: bpf <bpf@vger.kernel.org>, Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Dave Marchevsky <davemarchevsky@meta.com>,
	Delyan Kratunov <delyank@meta.com>
Subject: Re: [PATCH bpf-next v2 19/25] bpf: Introduce bpf_kptr_new
Date: Thu, 20 Oct 2022 06:14:45 +0530	[thread overview]
Message-ID: <20221020004445.zuwwtqe2qdk6ccfj@apollo> (raw)
In-Reply-To: <CAADnVQ+Q9LO1dkz-Q7jHRjgf5cFFk1go=gwYDfVrTtanjMCoHw@mail.gmail.com>

On Wed, Oct 19, 2022 at 10:01:21PM IST, Alexei Starovoitov wrote:
> On Tue, Oct 18, 2022 at 10:58 PM Kumar Kartikeya Dwivedi
> <memxor@gmail.com> wrote:
> >
> > On Wed, Oct 19, 2022 at 08:01:24AM IST, Alexei Starovoitov wrote:
> > > On Thu, Oct 13, 2022 at 11:52:57AM +0530, Kumar Kartikeya Dwivedi wrote:
> > > > +void *bpf_kptr_new_impl(u64 local_type_id__k, u64 flags, void *meta__ign)
> > > > +{
> > > > +   struct btf_struct_meta *meta = meta__ign;
> > > > +   u64 size = local_type_id__k;
> > > > +   void *p;
> > > > +
> > > > +   if (unlikely(flags || !bpf_global_ma_set))
> > > > +           return NULL;
> > >
> > > Unused 'flags' looks weird in unstable api. Just drop it?
> > > And keep it as:
> > > void *bpf_kptr_new(u64 local_type_id__k, struct btf_struct_meta *meta__ign);
> > >
> > > and in bpf_experimental.h:
> > >
> > > extern void *bpf_kptr_new(__u64 local_type_id) __ksym;
> > >
> > > since __ign args are ignored during kfunc type match
> > > the bpf progs can use it without #define.
> > >
> >
> > It's ignored during check_kfunc_call, but libbpf doesn't ignore that. The
> > prototypes will not be the same. I guess I'll have to teach it do that during
> > type match, but IDK how you feel about that.
>
> libbpf does the full type match, really?
> Could you point me to the code?
>

Not full type match, but the number of arguments must be same, so it won't allow
having kfunc as:

void *bpf_kptr_new(u64 local_type_id__k, struct btf_struct_meta *meta__ign);

in the kernel and ksym declaration in the program as:

extern void *bpf_kptr_new(__u64 local_type_id) __ksym;

I get:

libbpf: extern (func ksym) 'bpf_kptr_new_impl': func_proto [25] incompatible with kernel [60043]

vlen of func_proto in kernel type is 2, for us it will be 1.

> > Otherwise unless you want people to manually pass something to the ignored
> > argument, we have to hide it behind a macro.
> >
> > I actually like the macro on top, then I don't even pass the type ID but the
> > type. But that's a personal preference, and I don't feel strongly about it.
> >
> > So in C one does malloc(sizeof(*p)), here we'll just write
> > bpf_kptr_new(typeof(*p)). YMMV.
>
> bpf_kptr_new(typeof(*p)) is cleaner.
>

So if we're having a macro anyway, the thing above can be hidden behind it.

> > > > +   p = bpf_mem_alloc(&bpf_global_ma, size);
> > > > +   if (!p)
> > > > +           return NULL;
> > > > +   if (meta)
> > > > +           bpf_obj_init(meta->off_arr, p);
> > >
> > > I'm starting to dislike all that _arr and _tab suffixes in the verifier code base.
> > > It reminds me of programming style where people tried to add types into
> > > variable names. imo dropping _arr wouldn't be just fine.
> >
> > Ack, I'll do it in v3.
> >
> > Also, I'd like to invite people to please bikeshed a bit over the naming of the
> > APIs, e.g. whether it should be bpf_kptr_drop vs bpf_kptr_delete.
>
> bpf_kptr_drop is more precise.
> delete assumes instant free which is not the case here.
>
> How about
> extern void *__bpf_obj_new(__u64 local_type_id) __ksym;
> extern void bpf_obj_drop(void *obj) __ksym;
> #define bpf_obj_new(t) \
>  (t *)__bpf_obj_new(bpf_core_type_id_local(t));
>
> kptr means 'kernel pointer'.
> Here we have program supplied object.
> It feels 'obj' is better than 'kptr' in this context.
>

I agree, I'll rename it to bpf_obj_*.

Also, that __bpf_obj_new doesn't work yet in clang [0] but I think we can rename
it to that once clang is fixed.

 [0]: https://reviews.llvm.org/D136041

> > In the BPF list API, it's named bpf_list_del but it's actually distinct from how
> > list_del in the kernel works. So it does make sense to give them a different
> > name (like pop_front/pop_back and push_front/push_back)?
> >
> > Because even bpf_list_add takes bpf_list_head, in the kernel there's no
> > distinction between node and head, so you can do list_add on a node as well, but
> > it won't be possible with the kfunc (unless we overload the head argument to
> > also work with nodes).
> >
> > Later we'll probably have to add bpf_list_node_add etc. that add before or after
> > a node to make that work.
> >
> > The main question is whether it should closely resembly the linked list API in
> > the kernel, or can it steer away considerably from that?
>
> If we do doubly linked list we should allow delete in
> the middle with
> bpf_list_del_any(head, node)
>
> and
> bpf_list_pop_front/pop_back(head)
>
> bpf_list_add(node, head) would match kernel style,
> but I think it's cleaner to have head as 1st arg.
> In that sense new pop/push/_front/_back are cleaner.
> And similar for rbtree.
>
> If we keep (node, head) and (rb_node, rb_root) order
> we should keep kernel names.

There's also tradeoffs in how various operations are done.

Right now we have bpf_list_del and bpf_list_del_tail doing pop_front and
pop_back.

To replicate the same in kernel style API, you would do:

struct foo *f = bpf_list_first_entry_or_null(head);
if (!f) {}
bpf_list_del(&f->node);

Between those two calls, you might do bpf_list_last_entry -> bpf_list_del, the
verifier is going to have a hard time proving the aliasing of the two nodes, so
it will have to invalidate all pointers peeking into the list whenever something
modifies it. You would still be able to access memory but cannot pass it to list
ops anymore.

But I think we will pay this cost eventually anyway, people will add a peek
operation and such analysis would have to be done then. So I think it's unlikely
we can avoid this, and it might be better to make things more consistent and end
up mirroring the kernel list APIs.

WDYT?

  reply	other threads:[~2022-10-20  0:45 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-13  6:22 [PATCH bpf-next v2 00/25] Local kptrs, BPF linked lists Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 01/25] bpf: Document UAPI details for special BPF types Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 02/25] bpf: Allow specifying volatile type modifier for kptrs Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 03/25] bpf: Clobber stack slot when writing over spilled PTR_TO_BTF_ID Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 04/25] bpf: Fix slot type check in check_stack_write_var_off Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 05/25] bpf: Drop reg_type_may_be_refcounted_or_null Kumar Kartikeya Dwivedi
2022-10-19 16:04   ` Dave Marchevsky
2022-10-13  6:22 ` [PATCH bpf-next v2 06/25] bpf: Refactor kptr_off_tab into fields_tab Kumar Kartikeya Dwivedi
2022-10-19  1:35   ` Alexei Starovoitov
2022-10-19  5:42     ` Kumar Kartikeya Dwivedi
2022-10-19 15:54       ` Alexei Starovoitov
2022-10-19 23:57         ` Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 07/25] bpf: Consolidate spin_lock, timer management " Kumar Kartikeya Dwivedi
2022-10-19  1:40   ` Alexei Starovoitov
2022-10-19  5:43     ` Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 08/25] bpf: Refactor map->off_arr handling Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 09/25] bpf: Support bpf_list_head in map values Kumar Kartikeya Dwivedi
2022-10-19  1:59   ` Alexei Starovoitov
2022-10-19  5:48     ` Kumar Kartikeya Dwivedi
2022-10-19 15:57       ` Alexei Starovoitov
2022-10-19 23:59         ` Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 10/25] bpf: Introduce local kptrs Kumar Kartikeya Dwivedi
2022-10-13 13:48   ` kernel test robot
2022-10-19 17:15   ` Dave Marchevsky
2022-10-20  0:48     ` Kumar Kartikeya Dwivedi
2022-10-25 16:27       ` Dave Marchevsky
2022-10-25 18:11         ` Kumar Kartikeya Dwivedi
2022-10-25 16:32   ` Dave Marchevsky
2022-10-25 18:11     ` Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 11/25] bpf: Recognize bpf_{spin_lock,list_head,list_node} in " Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 12/25] bpf: Verify ownership relationships for owning types Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 13/25] bpf: Support locking bpf_spin_lock in local kptr Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 14/25] bpf: Allow locking bpf_spin_lock global variables Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 15/25] bpf: Rewrite kfunc argument handling Kumar Kartikeya Dwivedi
2022-10-13 13:48   ` kernel test robot
2022-10-13  6:22 ` [PATCH bpf-next v2 16/25] bpf: Drop kfunc bits from btf_check_func_arg_match Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 17/25] bpf: Support constant scalar arguments for kfuncs Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 18/25] bpf: Teach verifier about non-size constant arguments Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 19/25] bpf: Introduce bpf_kptr_new Kumar Kartikeya Dwivedi
2022-10-19  2:31   ` Alexei Starovoitov
2022-10-19  5:58     ` Kumar Kartikeya Dwivedi
2022-10-19 16:31       ` Alexei Starovoitov
2022-10-20  0:44         ` Kumar Kartikeya Dwivedi [this message]
2022-10-20  1:11           ` Alexei Starovoitov
2022-10-13  6:22 ` [PATCH bpf-next v2 20/25] bpf: Introduce bpf_kptr_drop Kumar Kartikeya Dwivedi
2022-10-13  6:22 ` [PATCH bpf-next v2 21/25] bpf: Permit NULL checking pointer with non-zero fixed offset Kumar Kartikeya Dwivedi
2022-10-13  6:23 ` [PATCH bpf-next v2 22/25] bpf: Introduce single ownership BPF linked list API Kumar Kartikeya Dwivedi
2022-10-25 17:45   ` Dave Marchevsky
2022-10-25 19:00     ` Kumar Kartikeya Dwivedi
2022-10-13  6:23 ` [PATCH bpf-next v2 23/25] libbpf: Add support for private BSS map section Kumar Kartikeya Dwivedi
2022-10-18  4:03   ` Andrii Nakryiko
2022-10-13  6:23 ` [PATCH bpf-next v2 24/25] selftests/bpf: Add __contains macro to bpf_experimental.h Kumar Kartikeya Dwivedi
2022-10-13  6:23 ` [PATCH bpf-next v2 25/25] selftests/bpf: Add BPF linked list API tests Kumar Kartikeya Dwivedi

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=20221020004445.zuwwtqe2qdk6ccfj@apollo \
    --to=memxor@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davemarchevsky@meta.com \
    --cc=delyank@meta.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.