mirror of
https://github.com/netdata/libbpf.git
synced 2026-04-08 09:39:07 +08:00
libbpf: Auto-attach struct_ops BPF maps in BPF skeleton
Similarly to `bpf_program`, support `bpf_map` automatic attachment in `bpf_object__attach_skeleton`. Currently only struct_ops maps could be attached. On bpftool side, code-generate links in skeleton struct for struct_ops maps. Similarly to `bpf_program_skeleton`, set links in `bpf_map_skeleton`. On libbpf side, extend `bpf_map` with new `autoattach` field to support enabling or disabling autoattach functionality, introducing getter/setter for this field. `bpf_object__(attach|detach)_skeleton` is extended with attaching/detaching struct_ops maps logic. Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20240605175135.117127-1-yatsenko@meta.com
This commit is contained in:
committed by
Andrii Nakryiko
parent
78c78e90cd
commit
be998aa3d4
64
src/libbpf.c
64
src/libbpf.c
@@ -572,6 +572,7 @@ struct bpf_map {
|
|||||||
bool pinned;
|
bool pinned;
|
||||||
bool reused;
|
bool reused;
|
||||||
bool autocreate;
|
bool autocreate;
|
||||||
|
bool autoattach;
|
||||||
__u64 map_extra;
|
__u64 map_extra;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1400,6 +1401,7 @@ static int init_struct_ops_maps(struct bpf_object *obj, const char *sec_name,
|
|||||||
map->def.value_size = type->size;
|
map->def.value_size = type->size;
|
||||||
map->def.max_entries = 1;
|
map->def.max_entries = 1;
|
||||||
map->def.map_flags = strcmp(sec_name, STRUCT_OPS_LINK_SEC) == 0 ? BPF_F_LINK : 0;
|
map->def.map_flags = strcmp(sec_name, STRUCT_OPS_LINK_SEC) == 0 ? BPF_F_LINK : 0;
|
||||||
|
map->autoattach = true;
|
||||||
|
|
||||||
map->st_ops = calloc(1, sizeof(*map->st_ops));
|
map->st_ops = calloc(1, sizeof(*map->st_ops));
|
||||||
if (!map->st_ops)
|
if (!map->st_ops)
|
||||||
@@ -4819,6 +4821,20 @@ int bpf_map__set_autocreate(struct bpf_map *map, bool autocreate)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bpf_map__set_autoattach(struct bpf_map *map, bool autoattach)
|
||||||
|
{
|
||||||
|
if (!bpf_map__is_struct_ops(map))
|
||||||
|
return libbpf_err(-EINVAL);
|
||||||
|
|
||||||
|
map->autoattach = autoattach;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bpf_map__autoattach(const struct bpf_map *map)
|
||||||
|
{
|
||||||
|
return map->autoattach;
|
||||||
|
}
|
||||||
|
|
||||||
int bpf_map__reuse_fd(struct bpf_map *map, int fd)
|
int bpf_map__reuse_fd(struct bpf_map *map, int fd)
|
||||||
{
|
{
|
||||||
struct bpf_map_info info;
|
struct bpf_map_info info;
|
||||||
@@ -12900,8 +12916,10 @@ struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map)
|
|||||||
__u32 zero = 0;
|
__u32 zero = 0;
|
||||||
int err, fd;
|
int err, fd;
|
||||||
|
|
||||||
if (!bpf_map__is_struct_ops(map))
|
if (!bpf_map__is_struct_ops(map)) {
|
||||||
|
pr_warn("map '%s': can't attach non-struct_ops map\n", map->name);
|
||||||
return libbpf_err_ptr(-EINVAL);
|
return libbpf_err_ptr(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
if (map->fd < 0) {
|
if (map->fd < 0) {
|
||||||
pr_warn("map '%s': can't attach BPF map without FD (was it created?)\n", map->name);
|
pr_warn("map '%s': can't attach BPF map without FD (was it created?)\n", map->name);
|
||||||
@@ -13945,6 +13963,35 @@ int bpf_object__attach_skeleton(struct bpf_object_skeleton *s)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skeleton is created with earlier version of bpftool
|
||||||
|
* which does not support auto-attachment
|
||||||
|
*/
|
||||||
|
if (s->map_skel_sz < sizeof(struct bpf_map_skeleton))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < s->map_cnt; i++) {
|
||||||
|
struct bpf_map *map = *s->maps[i].map;
|
||||||
|
struct bpf_link **link = s->maps[i].link;
|
||||||
|
|
||||||
|
if (!map->autocreate || !map->autoattach)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (*link)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* only struct_ops maps can be attached */
|
||||||
|
if (!bpf_map__is_struct_ops(map))
|
||||||
|
continue;
|
||||||
|
*link = bpf_map__attach_struct_ops(map);
|
||||||
|
|
||||||
|
if (!*link) {
|
||||||
|
err = -errno;
|
||||||
|
pr_warn("map '%s': failed to auto-attach: %d\n",
|
||||||
|
bpf_map__name(map), err);
|
||||||
|
return libbpf_err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13958,6 +14005,18 @@ void bpf_object__detach_skeleton(struct bpf_object_skeleton *s)
|
|||||||
bpf_link__destroy(*link);
|
bpf_link__destroy(*link);
|
||||||
*link = NULL;
|
*link = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->map_skel_sz < sizeof(struct bpf_map_skeleton))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < s->map_cnt; i++) {
|
||||||
|
struct bpf_link **link = s->maps[i].link;
|
||||||
|
|
||||||
|
if (link) {
|
||||||
|
bpf_link__destroy(*link);
|
||||||
|
*link = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s)
|
void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s)
|
||||||
@@ -13965,8 +14024,7 @@ void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s)
|
|||||||
if (!s)
|
if (!s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (s->progs)
|
bpf_object__detach_skeleton(s);
|
||||||
bpf_object__detach_skeleton(s);
|
|
||||||
if (s->obj)
|
if (s->obj)
|
||||||
bpf_object__close(*s->obj);
|
bpf_object__close(*s->obj);
|
||||||
free(s->maps);
|
free(s->maps);
|
||||||
|
|||||||
18
src/libbpf.h
18
src/libbpf.h
@@ -978,6 +978,23 @@ bpf_object__prev_map(const struct bpf_object *obj, const struct bpf_map *map);
|
|||||||
LIBBPF_API int bpf_map__set_autocreate(struct bpf_map *map, bool autocreate);
|
LIBBPF_API int bpf_map__set_autocreate(struct bpf_map *map, bool autocreate);
|
||||||
LIBBPF_API bool bpf_map__autocreate(const struct bpf_map *map);
|
LIBBPF_API bool bpf_map__autocreate(const struct bpf_map *map);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **bpf_map__set_autoattach()** sets whether libbpf has to auto-attach
|
||||||
|
* map during BPF skeleton attach phase.
|
||||||
|
* @param map the BPF map instance
|
||||||
|
* @param autoattach whether to attach map during BPF skeleton attach phase
|
||||||
|
* @return 0 on success; negative error code, otherwise
|
||||||
|
*/
|
||||||
|
LIBBPF_API int bpf_map__set_autoattach(struct bpf_map *map, bool autoattach);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **bpf_map__autoattach()** returns whether BPF map is configured to
|
||||||
|
* auto-attach during BPF skeleton attach phase.
|
||||||
|
* @param map the BPF map instance
|
||||||
|
* @return true if map is set to auto-attach during skeleton attach phase; false, otherwise
|
||||||
|
*/
|
||||||
|
LIBBPF_API bool bpf_map__autoattach(const struct bpf_map *map);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief **bpf_map__fd()** gets the file descriptor of the passed
|
* @brief **bpf_map__fd()** gets the file descriptor of the passed
|
||||||
* BPF map
|
* BPF map
|
||||||
@@ -1672,6 +1689,7 @@ struct bpf_map_skeleton {
|
|||||||
const char *name;
|
const char *name;
|
||||||
struct bpf_map **map;
|
struct bpf_map **map;
|
||||||
void **mmaped;
|
void **mmaped;
|
||||||
|
struct bpf_link **link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bpf_prog_skeleton {
|
struct bpf_prog_skeleton {
|
||||||
|
|||||||
@@ -419,6 +419,8 @@ LIBBPF_1.4.0 {
|
|||||||
|
|
||||||
LIBBPF_1.5.0 {
|
LIBBPF_1.5.0 {
|
||||||
global:
|
global:
|
||||||
|
bpf_map__autoattach;
|
||||||
|
bpf_map__set_autoattach;
|
||||||
bpf_program__attach_sockmap;
|
bpf_program__attach_sockmap;
|
||||||
ring__consume_n;
|
ring__consume_n;
|
||||||
ring_buffer__consume_n;
|
ring_buffer__consume_n;
|
||||||
|
|||||||
Reference in New Issue
Block a user