On Tue, Mar 15, 2022 at 3:15 PM Delyan Kratunov <delyank@xxxxxx> wrote: > > In symmetry with bpf_object__open_skeleton(), > bpf_object__open_subskeleton() performs the actual walking and linking > of maps, progs, and globals described by bpf_*_skeleton objects. > > Signed-off-by: Delyan Kratunov <delyank@xxxxxx> > --- > tools/lib/bpf/libbpf.c | 136 +++++++++++++++++++++++++++++++++------ > tools/lib/bpf/libbpf.h | 29 +++++++++ > tools/lib/bpf/libbpf.map | 2 + > 3 files changed, 146 insertions(+), 21 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index e98a8381aad8..dac905171aaf 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -11812,6 +11812,49 @@ int libbpf_num_possible_cpus(void) > return tmp_cpus; > } > [...] > +int bpf_object__open_subskeleton(struct bpf_object_subskeleton *s) > +{ > + int err, len, var_idx, i; > + const char *var_name; > + const struct bpf_map *map; > + struct btf *btf; > + __u32 map_type_id; > + const struct btf_type *map_type, *var_type; > + const struct bpf_var_skeleton *var_skel; > + struct btf_var_secinfo *var; > + > + if (!s->obj) > + return libbpf_err(-EINVAL); > + > + btf = bpf_object__btf(s->obj); > + if (!btf) > + return libbpf_err(-errno); can you please add an error message here that subskeletons expect bpf_object to have BTF? Might be very confusing to users to understand what's wrong if this happens > + > + err = populate_skeleton_maps(s->obj, s->maps, s->map_cnt); > + if (err) { > + pr_warn("failed to populate subskeleton maps: %d\n", err); > + return libbpf_err(err); > } > > - for (i = 0; i < s->prog_cnt; i++) { > - struct bpf_program **prog = s->progs[i].prog; > - const char *name = s->progs[i].name; > + err = populate_skeleton_progs(s->obj, s->progs, s->prog_cnt); > + if (err) { > + pr_warn("failed to populate subskeleton maps: %d\n", err); > + return libbpf_err(err); > + } > > - *prog = bpf_object__find_program_by_name(obj, name); > - if (!*prog) { > - pr_warn("failed to find skeleton program '%s'\n", name); > - return libbpf_err(-ESRCH); > + for (var_idx = 0; var_idx < s->var_cnt; var_idx++) { > + var_skel = &s->vars[var_idx]; > + map = *var_skel->map; > + map_type_id = bpf_map__btf_value_type_id(map); > + map_type = btf__type_by_id(btf, map_type_id); > + > + if (!btf_is_datasec(map_type)) { > + pr_warn("Type for map '%1$s' is not a datasec: %2$s", > + bpf_map__name(map), > + __btf_kind_str(btf_kind(map_type))); nit: other messages in this function start with lower case, let's keep it consistent. But I think this is very unlikely error, so I think it would be fine without pr_warn() altogether (missing BTF above seems more probable) > + return libbpf_err(-EINVAL); > } > - } > > + len = btf_vlen(map_type); > + var = btf_var_secinfos(map_type); > + for (i = 0; i < len; i++, var++) { > + var_type = btf__type_by_id(btf, var->type); > + var_name = btf__name_by_offset(btf, var_type->name_off); > + if (strcmp(var_name, var_skel->name) == 0) { > + *var_skel->addr = map->mmaped + var->offset; > + break; > + } > + } > + } > return 0; > } > [...]