On Tue, Mar 12, 2024 at 9:49 AM Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> wrote: > > On Mon, Mar 11, 2024 at 2:34 AM Menglong Dong > <dongmenglong.8@xxxxxxxxxxxxx> wrote: > > > > Refactor the struct modules_array to more general struct ptr_array, which > > is used to store the pointers. > > > > Meanwhiles, introduce the bpf_try_add_ptr(), which checks the existing of > > the ptr before adding it to the array. > > > > Seems it should be moved to another files in "lib", and I'm not sure where > > to add it now, and let's move it to kernel/bpf/syscall.c for now. > > > > Signed-off-by: Menglong Dong <dongmenglong.8@xxxxxxxxxxxxx> > > --- > > include/linux/bpf.h | 10 +++++++++ > > kernel/bpf/syscall.c | 37 +++++++++++++++++++++++++++++++ > > kernel/trace/bpf_trace.c | 48 ++++++---------------------------------- > > 3 files changed, 54 insertions(+), 41 deletions(-) > > > > diff --git a/include/linux/bpf.h b/include/linux/bpf.h > > index 0f677fdcfcc7..997765cdf474 100644 > > --- a/include/linux/bpf.h > > +++ b/include/linux/bpf.h > > @@ -304,6 +304,16 @@ struct bpf_map { > > s64 __percpu *elem_count; > > }; > > > > +struct ptr_array { > > + void **ptrs; > > + int cnt; > > + int cap; > > +}; > > + > > +int bpf_add_ptr(struct ptr_array *arr, void *ptr); > > +bool bpf_has_ptr(struct ptr_array *arr, struct module *mod); > > +int bpf_try_add_ptr(struct ptr_array *arr, void *ptr); > > + > > static inline const char *btf_field_type_name(enum btf_field_type type) > > { > > switch (type) { > > diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c > > index f63f4da4db5e..4f230fd1f8e4 100644 > > --- a/kernel/bpf/syscall.c > > +++ b/kernel/bpf/syscall.c > > @@ -479,6 +479,43 @@ static void bpf_map_release_memcg(struct bpf_map *map) > > } > > #endif > > > > +int bpf_add_ptr(struct ptr_array *arr, void *ptr) > > +{ > > + void **ptrs; > > + > > + if (arr->cnt == arr->cap) { > > + arr->cap = max(16, arr->cap * 3 / 2); > > + ptrs = krealloc_array(arr->ptrs, arr->cap, sizeof(*ptrs), GFP_KERNEL); > > + if (!ptrs) > > + return -ENOMEM; > > + arr->ptrs = ptrs; > > + } > > + > > + arr->ptrs[arr->cnt] = ptr; > > + arr->cnt++; > > + return 0; > > +} > > + > > +bool bpf_has_ptr(struct ptr_array *arr, struct module *mod) > > Don't you need 'void *mod' here? > Oops, it should be void *ptr here, my mistake~ > > +{ > > + int i; > > + > > + for (i = arr->cnt - 1; i >= 0; i--) { > > + if (arr->ptrs[i] == mod) > > + return true; > > + } > > + return false; > > +} > > ... > > > - kprobe_multi_put_modules(arr.mods, arr.mods_cnt); > > - kfree(arr.mods); > > + kprobe_multi_put_modules((struct module **)arr.ptrs, arr.cnt); > > Do you really need to type cast? Compiler doesn't convert void** > automatically? Yeah, the compiler reports errors without this casting.