Re: [PATCH bpf-next v2 1/2] libbpf: Support static initialization of BPF_MAP_TYPE_PROG_ARRAY

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Nov 28, 2021 at 6:17 AM Hengqi Chen <hengqi.chen@xxxxxxxxx> wrote:
>
> Support static initialization of BPF_MAP_TYPE_PROG_ARRAY with a
> syntax similar to map-in-map initialization ([0]):
>
>     SEC("socket")
>     int tailcall_1(void *ctx)
>     {
>         return 0;
>     }
>
>     struct {
>         __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
>         __uint(max_entries, 2);
>         __uint(key_size, sizeof(__u32));
>         __array(values, int (void *));
>     } prog_array_init SEC(".maps") = {
>         .values = {
>             [1] = (void *)&tailcall_1,
>         },
>     };
>
> Here's the relevant part of libbpf debug log showing what's
> going on with prog-array initialization:
>
> libbpf: sec '.relsocket': collecting relocation for section(3) 'socket'
> libbpf: sec '.relsocket': relo #0: insn #2 against 'prog_array_init'
> libbpf: prog 'entry': found map 0 (prog_array_init, sec 4, off 0) for insn #0
> libbpf: .maps relo #0: for 3 value 0 rel->r_offset 32 name 53 ('tailcall_1')
> libbpf: .maps relo #0: map 'prog_array_init' slot [1] points to prog 'tailcall_1'
> libbpf: map 'prog_array_init': created successfully, fd=5
> libbpf: map 'prog_array_init': slot [1] set to prog 'tailcall_1' fd=6
>
>   [0] Closes: https://github.com/libbpf/libbpf/issues/354
>
> Signed-off-by: Hengqi Chen <hengqi.chen@xxxxxxxxx>
> ---
>  tools/lib/bpf/libbpf.c | 139 ++++++++++++++++++++++++++++++++---------
>  1 file changed, 111 insertions(+), 28 deletions(-)
>

[...]

> -               targ_map = bpf_object__find_map_by_name(obj, name);
> -               if (!targ_map)
> -                       return -ESRCH;
> +               if (is_map_in_map) {
> +                       targ_map = bpf_object__find_map_by_name(obj, name);
> +                       if (!targ_map)
> +                               return -ESRCH;
> +               }
> +               if (is_prog_array) {
> +                       targ_prog = bpf_object__find_program_by_name(obj, name);
> +                       if (!targ_prog)
> +                               return -ESRCH;
> +                       if (targ_prog->sec_idx != sym->st_shndx ||
> +                           targ_prog->sec_insn_off * 8 != sym->st_value ||
> +                           prog_is_subprog(obj, targ_prog)) {
> +                               pr_warn(".maps relo #%d: '%s' isn't an entry-point BPF program\n",
> +                                       i, name);
> +                               return -LIBBPF_ERRNO__RELOC;
> +                       }
> +               }

I've slightly adjusted this part to have an exhaustive if
(is_map_in_map) else if (is_prog_array) else { return -EINVAL; }. I've
also added an error message when someone is trying to put non-BPF
program into BPF_MAP_TYPE_PROG_ARRAY, like this:

  libbpf: .maps relo #0: 'value' isn't a valid program reference

Awesome work, applied to bpf-next, thanks.

>
>                 var = btf__type_by_id(obj->btf, vi->type);
>                 def = skip_mods_and_typedefs(obj->btf, var->type, NULL);
> @@ -6287,10 +6369,10 @@ static int bpf_object__collect_map_relos(struct bpf_object *obj,
>                                (new_sz - map->init_slots_sz) * host_ptr_sz);
>                         map->init_slots_sz = new_sz;
>                 }
> -               map->init_slots[moff] = targ_map;
> +               map->init_slots[moff] = is_map_in_map ? (void *)targ_map : (void *)targ_prog;
>
> -               pr_debug(".maps relo #%d: map '%s' slot [%d] points to map '%s'\n",
> -                        i, map->name, moff, name);
> +               pr_debug(".maps relo #%d: map '%s' slot [%d] points to %s '%s'\n",
> +                        i, map->name, moff, type, name);
>         }
>
>         return 0;
> @@ -7304,6 +7386,7 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
>         err = err ? : bpf_object__create_maps(obj);
>         err = err ? : bpf_object__relocate(obj, obj->btf_custom_path ? : attr->target_btf_path);
>         err = err ? : bpf_object__load_progs(obj, attr->log_level);
> +       err = err ? : bpf_object_init_prog_arrays(obj);
>
>         if (obj->gen_loader) {
>                 /* reset FDs */
> --
> 2.30.2



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux