mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
libbpf: Add subskeleton scaffolding
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@fb.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/6942a46fbe20e7ebf970affcca307ba616985b15.1647473511.git.delyank@fb.com
This commit is contained in:
parent
262cfb74ff
commit
430025e5dc
3 changed files with 153 additions and 25 deletions
|
@ -11989,6 +11989,49 @@ int libbpf_num_possible_cpus(void)
|
||||||
return tmp_cpus;
|
return tmp_cpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int populate_skeleton_maps(const struct bpf_object *obj,
|
||||||
|
struct bpf_map_skeleton *maps,
|
||||||
|
size_t map_cnt)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < map_cnt; i++) {
|
||||||
|
struct bpf_map **map = maps[i].map;
|
||||||
|
const char *name = maps[i].name;
|
||||||
|
void **mmaped = maps[i].mmaped;
|
||||||
|
|
||||||
|
*map = bpf_object__find_map_by_name(obj, name);
|
||||||
|
if (!*map) {
|
||||||
|
pr_warn("failed to find skeleton map '%s'\n", name);
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* externs shouldn't be pre-setup from user code */
|
||||||
|
if (mmaped && (*map)->libbpf_type != LIBBPF_MAP_KCONFIG)
|
||||||
|
*mmaped = (*map)->mmaped;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int populate_skeleton_progs(const struct bpf_object *obj,
|
||||||
|
struct bpf_prog_skeleton *progs,
|
||||||
|
size_t prog_cnt)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < prog_cnt; i++) {
|
||||||
|
struct bpf_program **prog = progs[i].prog;
|
||||||
|
const char *name = progs[i].name;
|
||||||
|
|
||||||
|
*prog = bpf_object__find_program_by_name(obj, name);
|
||||||
|
if (!*prog) {
|
||||||
|
pr_warn("failed to find skeleton program '%s'\n", name);
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int bpf_object__open_skeleton(struct bpf_object_skeleton *s,
|
int bpf_object__open_skeleton(struct bpf_object_skeleton *s,
|
||||||
const struct bpf_object_open_opts *opts)
|
const struct bpf_object_open_opts *opts)
|
||||||
{
|
{
|
||||||
|
@ -11996,7 +12039,7 @@ int bpf_object__open_skeleton(struct bpf_object_skeleton *s,
|
||||||
.object_name = s->name,
|
.object_name = s->name,
|
||||||
);
|
);
|
||||||
struct bpf_object *obj;
|
struct bpf_object *obj;
|
||||||
int i, err;
|
int err;
|
||||||
|
|
||||||
/* Attempt to preserve opts->object_name, unless overriden by user
|
/* Attempt to preserve opts->object_name, unless overriden by user
|
||||||
* explicitly. Overwriting object name for skeletons is discouraged,
|
* explicitly. Overwriting object name for skeletons is discouraged,
|
||||||
|
@ -12019,37 +12062,91 @@ int bpf_object__open_skeleton(struct bpf_object_skeleton *s,
|
||||||
}
|
}
|
||||||
|
|
||||||
*s->obj = obj;
|
*s->obj = obj;
|
||||||
|
err = populate_skeleton_maps(obj, s->maps, s->map_cnt);
|
||||||
for (i = 0; i < s->map_cnt; i++) {
|
if (err) {
|
||||||
struct bpf_map **map = s->maps[i].map;
|
pr_warn("failed to populate skeleton maps for '%s': %d\n", s->name, err);
|
||||||
const char *name = s->maps[i].name;
|
return libbpf_err(err);
|
||||||
void **mmaped = s->maps[i].mmaped;
|
|
||||||
|
|
||||||
*map = bpf_object__find_map_by_name(obj, name);
|
|
||||||
if (!*map) {
|
|
||||||
pr_warn("failed to find skeleton map '%s'\n", name);
|
|
||||||
return libbpf_err(-ESRCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* externs shouldn't be pre-setup from user code */
|
|
||||||
if (mmaped && (*map)->libbpf_type != LIBBPF_MAP_KCONFIG)
|
|
||||||
*mmaped = (*map)->mmaped;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < s->prog_cnt; i++) {
|
err = populate_skeleton_progs(obj, s->progs, s->prog_cnt);
|
||||||
struct bpf_program **prog = s->progs[i].prog;
|
if (err) {
|
||||||
const char *name = s->progs[i].name;
|
pr_warn("failed to populate skeleton progs for '%s': %d\n", s->name, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
pr_warn("subskeletons require BTF at runtime (object %s)\n",
|
||||||
|
bpf_object__name(s->obj));
|
||||||
|
return libbpf_err(-errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bpf_object__destroy_subskeleton(struct bpf_object_subskeleton *s)
|
||||||
|
{
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
free(s->maps);
|
||||||
|
free(s->progs);
|
||||||
|
free(s->vars);
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
int bpf_object__load_skeleton(struct bpf_object_skeleton *s)
|
int bpf_object__load_skeleton(struct bpf_object_skeleton *s)
|
||||||
{
|
{
|
||||||
int i, err;
|
int i, err;
|
||||||
|
|
|
@ -1312,6 +1312,35 @@ LIBBPF_API int bpf_object__attach_skeleton(struct bpf_object_skeleton *s);
|
||||||
LIBBPF_API void bpf_object__detach_skeleton(struct bpf_object_skeleton *s);
|
LIBBPF_API void bpf_object__detach_skeleton(struct bpf_object_skeleton *s);
|
||||||
LIBBPF_API void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s);
|
LIBBPF_API void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s);
|
||||||
|
|
||||||
|
struct bpf_var_skeleton {
|
||||||
|
const char *name;
|
||||||
|
struct bpf_map **map;
|
||||||
|
void **addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpf_object_subskeleton {
|
||||||
|
size_t sz; /* size of this struct, for forward/backward compatibility */
|
||||||
|
|
||||||
|
const struct bpf_object *obj;
|
||||||
|
|
||||||
|
int map_cnt;
|
||||||
|
int map_skel_sz; /* sizeof(struct bpf_map_skeleton) */
|
||||||
|
struct bpf_map_skeleton *maps;
|
||||||
|
|
||||||
|
int prog_cnt;
|
||||||
|
int prog_skel_sz; /* sizeof(struct bpf_prog_skeleton) */
|
||||||
|
struct bpf_prog_skeleton *progs;
|
||||||
|
|
||||||
|
int var_cnt;
|
||||||
|
int var_skel_sz; /* sizeof(struct bpf_var_skeleton) */
|
||||||
|
struct bpf_var_skeleton *vars;
|
||||||
|
};
|
||||||
|
|
||||||
|
LIBBPF_API int
|
||||||
|
bpf_object__open_subskeleton(struct bpf_object_subskeleton *s);
|
||||||
|
LIBBPF_API void
|
||||||
|
bpf_object__destroy_subskeleton(struct bpf_object_subskeleton *s);
|
||||||
|
|
||||||
struct gen_loader_opts {
|
struct gen_loader_opts {
|
||||||
size_t sz; /* size of this struct, for forward/backward compatiblity */
|
size_t sz; /* size of this struct, for forward/backward compatiblity */
|
||||||
const char *data;
|
const char *data;
|
||||||
|
|
|
@ -442,6 +442,8 @@ LIBBPF_0.7.0 {
|
||||||
|
|
||||||
LIBBPF_0.8.0 {
|
LIBBPF_0.8.0 {
|
||||||
global:
|
global:
|
||||||
|
bpf_object__destroy_subskeleton;
|
||||||
|
bpf_object__open_subskeleton;
|
||||||
libbpf_register_prog_handler;
|
libbpf_register_prog_handler;
|
||||||
libbpf_unregister_prog_handler;
|
libbpf_unregister_prog_handler;
|
||||||
bpf_program__attach_kprobe_multi_opts;
|
bpf_program__attach_kprobe_multi_opts;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue