On 11/3/22 3:10 PM, Kumar Kartikeya Dwivedi wrote: > Introduce type safe memory allocator bpf_obj_new for BPF programs. The > kernel side kfunc is named bpf_obj_new_impl, as passing hidden arguments > to kfuncs still requires having them in prototype, unlike BPF helpers > which always take 5 arguments and have them checked using bpf_func_proto > in verifier, ignoring unset argument types. > > Introduce __ign suffix to ignore a specific kfunc argument during type > checks, then use this to introduce support for passing type metadata to > the bpf_obj_new_impl kfunc. > > The user passes BTF ID of the type it wants to allocates in program BTF, > the verifier then rewrites the first argument as the size of this type, > after performing some sanity checks (to ensure it exists and it is a > struct type). > > The second argument is also fixed up and passed by the verifier. This is > the btf_struct_meta for the type being allocated. It would be needed > mostly for the offset array which is required for zero initializing > special fields while leaving the rest of storage in unitialized state. > > It would also be needed in the next patch to perform proper destruction > of the object's special fields. > > A convenience macro is included in the bpf_experimental.h header to hide > over the ugly details of the implementation, leading to user code > looking similar to a language level extension which allocates and > constructs fields of a user type. > > struct bar { > struct bpf_list_node node; > }; > > struct foo { > struct bpf_spin_lock lock; > struct bpf_list_head head __contains(bar, node); > }; > > void prog(void) { > struct foo *f; > > f = bpf_obj_new(typeof(*f)); > if (!f) > return; > ... > } > > A key piece of this story is still missing, i.e. the free function, > which will come in the next patch. > > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> > --- [...] > diff --git a/tools/testing/selftests/bpf/bpf_experimental.h b/tools/testing/selftests/bpf/bpf_experimental.h > new file mode 100644 > index 000000000000..1d3451084a68 > --- /dev/null > +++ b/tools/testing/selftests/bpf/bpf_experimental.h Maybe bpf_experimental.h should go in libbpf as part of this series? If including vmlinux.h is an issue - nothing in libbpf currently includes it - you could rely on the BPF program including it, with a comment similar to "Note that bpf programs need to include..." in lib/bpf/bpf_helpers.h . > @@ -0,0 +1,20 @@ > +#include <vmlinux.h> > +#include <bpf/bpf_tracing.h> > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_core_read.h> > + > +/* Description > + * Allocates a local kptr of type represented by 'local_type_id' in program > + * BTF. User may use the bpf_core_type_id_local macro to pass the type ID > + * of a struct in program BTF. > + * > + * The 'local_type_id' parameter must be a known constant. > + * The 'meta' parameter is a hidden argument that is ignored. > + * Returns > + * A local kptr corresponding to passed in 'local_type_id', or NULL on > + * failure. > + */ > +extern void *bpf_obj_new_impl(__u64 local_type_id, void *meta) __ksym; > + > +/* Convenience macro to wrap over bpf_obj_new_impl */ > +#define bpf_obj_new(type) bpf_obj_new_impl(bpf_core_type_id_local(type), NULL)