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? > +{ > + 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?