mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
bpf: Add bpf_struct_ops_for_each_prog()
Add a helper that walks the member progs of the struct_ops map containing a given @kdata vmtable. struct_ops ->reg() callbacks (and similar) sometimes need to inspect the loaded BPF programs, e.g. to discover maps they reference via prog->aux->used_maps. The implementation mirrors bpf_struct_ops_id(): container_of @kdata to recover the bpf_struct_ops_map, then iterate st_map->links[i]->prog for i in [0, funcs_cnt). Same access pattern, no new locking - by the time ->reg() fires st_map is fully populated and stable. A sched_ext follow-up walks the member progs of a cid-form scheduler's struct_ops map, reads prog->aux->arena directly, and requires all member progs to reference exactly one arena, without requiring the BPF program to call a registration kfunc. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/r/20260522172219.1423324-5-tj@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
f211c81ddc
commit
7c48a28c1b
|
|
@ -2131,6 +2131,9 @@ int bpf_prog_assoc_struct_ops(struct bpf_prog *prog, struct bpf_map *map);
|
|||
void bpf_prog_disassoc_struct_ops(struct bpf_prog *prog);
|
||||
void *bpf_prog_get_assoc_struct_ops(const struct bpf_prog_aux *aux);
|
||||
u32 bpf_struct_ops_id(const void *kdata);
|
||||
int bpf_struct_ops_for_each_prog(const void *kdata,
|
||||
int (*cb)(struct bpf_prog *prog, void *data),
|
||||
void *data);
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
/* Define it here to avoid the use of forward declaration */
|
||||
|
|
|
|||
|
|
@ -1204,6 +1204,42 @@ u32 bpf_struct_ops_id(const void *kdata)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(bpf_struct_ops_id);
|
||||
|
||||
/**
|
||||
* bpf_struct_ops_for_each_prog - Invoke @cb for each member prog
|
||||
* @kdata: kernel-side struct_ops vmtable (the @kdata arg to ->reg/->update/->unreg)
|
||||
* @cb: callback invoked once per member prog; non-zero return stops iteration
|
||||
* @data: opaque argument passed to @cb
|
||||
*
|
||||
* Walks the struct_ops member progs registered on the map containing @kdata.
|
||||
* Intended for use from struct_ops ->reg() callbacks (and similar) that need to
|
||||
* inspect the loaded BPF programs (for example to discover maps they reference
|
||||
* via @prog->aux->used_maps).
|
||||
*
|
||||
* Return 0 if iteration completed, otherwise the first non-zero @cb return.
|
||||
*/
|
||||
int bpf_struct_ops_for_each_prog(const void *kdata,
|
||||
int (*cb)(struct bpf_prog *prog, void *data),
|
||||
void *data)
|
||||
{
|
||||
struct bpf_struct_ops_value *kvalue;
|
||||
struct bpf_struct_ops_map *st_map;
|
||||
u32 i;
|
||||
int ret;
|
||||
|
||||
kvalue = container_of(kdata, struct bpf_struct_ops_value, data);
|
||||
st_map = container_of(kvalue, struct bpf_struct_ops_map, kvalue);
|
||||
|
||||
for (i = 0; i < st_map->funcs_cnt; i++) {
|
||||
if (!st_map->links[i])
|
||||
continue;
|
||||
ret = cb(st_map->links[i]->prog, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bpf_struct_ops_for_each_prog);
|
||||
|
||||
static bool bpf_struct_ops_valid_to_reg(struct bpf_map *map)
|
||||
{
|
||||
struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user