Re: [RFC PATCH 5/9] bpf: Add bpf_prog_for_each_used_map()
From: Kumar Kartikeya Dwivedi
Date: Mon May 11 2026 - 17:45:57 EST
On Mon, 27 Apr 2026 at 12:51, Tejun Heo <tj@xxxxxxxxxx> wrote:
>
> Wrap the prog->aux->used_maps[] walk and its used_maps_mutex behind a
> helper. Existing in-tree callers open-code the same lock + iterate pattern
> (e.g. bpf_check_tail_call in core.c, the verifier and syscall paths); a
> sched_ext follow-up needs the same loop and would otherwise reach into
> bpf_prog_aux directly.
>
> Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>
> ---
> include/linux/bpf.h | 3 +++
> kernel/bpf/core.c | 29 +++++++++++++++++++++++++++++
> 2 files changed, 32 insertions(+)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index f4e4360b81f6..587e5ff387bf 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -2338,6 +2338,9 @@ static inline bool map_type_contains_progs(struct bpf_map *map)
>
> bool bpf_prog_map_compatible(struct bpf_map *map, const struct bpf_prog *fp);
> int bpf_prog_calc_tag(struct bpf_prog *fp);
> +int bpf_prog_for_each_used_map(struct bpf_prog *prog,
> + int (*cb)(struct bpf_map *map, void *data),
> + void *data);
>
> const struct bpf_func_proto *bpf_get_trace_printk_proto(void);
> const struct bpf_func_proto *bpf_get_trace_vprintk_proto(void);
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 066b86e7233c..aa590a817176 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -2510,6 +2510,35 @@ static int bpf_check_tail_call(const struct bpf_prog *fp)
> return ret;
> }
>
> +/**
> + * bpf_prog_for_each_used_map - Invoke @cb for each map @prog references
> + * @prog: BPF program whose used_maps to walk
> + * @cb: callback invoked once per map; non-zero return stops iteration
> + * @data: opaque argument passed to @cb
> + *
> + * Holds prog->aux->used_maps_mutex across the walk.
> + *
> + * Return 0 if iteration completed, otherwise the first non-zero @cb return.
> + */
> +int bpf_prog_for_each_used_map(struct bpf_prog *prog,
> + int (*cb)(struct bpf_map *map, void *data),
> + void *data)
> +{
> + struct bpf_prog_aux *aux = prog->aux;
> + int ret = 0;
> + u32 i;
> +
> + mutex_lock(&aux->used_maps_mutex);
> + for (i = 0; i < aux->used_map_cnt; i++) {
> + ret = cb(aux->used_maps[i], data);
> + if (ret)
> + break;
> + }
> + mutex_unlock(&aux->used_maps_mutex);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(bpf_prog_for_each_used_map);
> +
Since each program only has one arena, and you use this to determine
whether the program's arena has a flag, why not just add a
bpf_prog_arena() accessor and check the result's flag directly? You
can do prog->aux->arena inside it to return the bpf_map pointer.
> static bool bpf_prog_select_interpreter(struct bpf_prog *fp)
> {
> bool select_interpreter = false;
> --
> 2.53.0
>