Re: [PATCH bpf-next v3 08/15] bpf: Add a few bpf_cgroup_array_* helper functions
Amery Hung <[email protected]>
| Newsgroups | org.kernel.vger.netdev,org.kernel.vger.bpf |
|---|---|
| Message-ID | <CAMB2axO0dhqd71m+PGo51RbjFHsztD3=0B7sxg-aCSKg9j1C6g@mail.gmail.com> |
On Mon, Jul 13, 2026 at 2:57 PM Emil Tsalapatis <[email protected]> wrote: > > On Mon Jul 6, 2026 at 1:19 PM EDT, Amery Hung wrote: > > From: Martin KaFai Lau <[email protected]> > > > > In the upcoming patch, the array can store a struct_ops map. > > The array could have a cfi_stubs acting as a dummy instead of > > the dummy_bpf_prog. The array logic will need to skip the cfi_stubs > > also in order to support storing struct_ops map in the array. > > > > bpf_cgroup_array_length(), bpf_cgroup_array_copy_to_user(), and > > bpf_cgroup_array_delete_safe_at() are added as a preparation work > > to allow skipping the cfi_stubs in the upcoming patch. This patch > > only skips the dummy_bpf_prog which is the same as the existing behavior. > > The current bpf_prog_array_*() callers are changed to call the new > > bpf_cgroup_array_*(). This is a no-op change. > > > > Unlike bpf_prog_array_copy_to_user(), bpf_cgroup_array_copy_to_user() > > does not need a temporary buffer. The cgroup caller already holds > > cgroup_mutex and dereferences the effective array with > > rcu_dereference_protected(), so it does not copy to userspace > > from an RCU read-side critical section. Details in commit 0911287ce32b. > > > > Another addition is the bpf_cgroup_array_free(). This prepares > > the array to have a different rcu gp for the struct_ops use case, > > for example, a struct_ops could have mix of sleepable ops and > > non-sleepable ops. In this patch, bpf_cgroup_array_free() only > > goes through the regular rcu gp. This is a no-op change also. > > > > bpf_prog_dummy() is also added to return the global dummy_bpf_prog. > > > > bpf_cgroup_array_dummy() is added to decide the sentinel based on atype. > > It now always returns bpf_prog_dummy(). In the upcoming patch, > > it can return a cfi_stubs if the atype belongs to a struct_ops. > > > > Signed-off-by: Martin KaFai Lau <[email protected]> > > Signed-off-by: Amery Hung <[email protected]> > > Reviewed-by: Emil Tsalapatis <[email protected]> > > One style issue below. > > > --- > > include/linux/bpf.h | 1 + > > kernel/bpf/cgroup.c | 79 +++++++++++++++++++++++++++++++++++++++------ > > kernel/bpf/core.c | 5 +++ > > 3 files changed, 76 insertions(+), 9 deletions(-) > > > > diff --git a/include/linux/bpf.h b/include/linux/bpf.h > > index 047ffc029666..e371a4733135 100644 > > --- a/include/linux/bpf.h > > +++ b/include/linux/bpf.h > > @@ -2561,6 +2561,7 @@ int bpf_prog_array_copy(struct bpf_prog_array *old_array, > > struct bpf_prog *include_prog, > > u64 bpf_cookie, > > struct bpf_prog_array **new_array); > > +struct bpf_prog *bpf_prog_dummy(void); > > > > struct bpf_run_ctx {}; > > > > diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c > > index 7abbe12e108f..081d81de1816 100644 > > --- a/kernel/bpf/cgroup.c > > +++ b/kernel/bpf/cgroup.c > > @@ -319,6 +319,67 @@ static void bpf_cgroup_link_auto_detach(struct bpf_cgroup_link *link) > > link->cgroup = NULL; > > } > > > > +static void bpf_cgroup_array_free(struct bpf_prog_array *array) > > +{ > > + if (!array || array == &bpf_empty_prog_array) > > + return; > > + kfree_rcu(array, rcu); > > +} > > + > > +static void *bpf_cgroup_array_dummy(enum cgroup_bpf_attach_type atype) > > +{ > > + return bpf_prog_dummy(); > > +} > > + > > +static int bpf_cgroup_array_length(struct bpf_prog_array *array, > > + enum cgroup_bpf_attach_type atype) > > +{ > > + struct bpf_prog_array_item *item; > > + int cnt = 0; > > + > > + for (item = array->items; item->prog; item++) > > + if (item->prog != bpf_cgroup_array_dummy(atype)) > > + cnt++; > > The outer parenthesis needs braces since its body is an if-statement. Ack. I will add the braces. [...]