libbpf: Add new interfaces
Subsystems (4)
cover libbpf: Add new interfaces
The patch set adds a couple of new interfaces to libbpf:
Patch 1 adds bpf_map__resize() to resize map before loading bpf_object; Patch 2 adds bpf_object__btf() to get struct btf * from bpf_object__btf.
Andrey Ignatov (2):
libbpf: Introduce bpf_map__resize
libbpf: Introduce bpf_object__btf
tools/lib/bpf/libbpf.c | 19 +++++++++++++++++++ tools/lib/bpf/libbpf.h | 4 ++++ tools/lib/bpf/libbpf.map | 2 ++ 3 files changed, 25 insertions(+)
Signature · 1 line
2.17.1
PATCH 1/2 libbpf: Introduce bpf_map__resize
Add bpf_map__resize() to change max_entries for a map.
Quite often necessary map size is unknown at compile time and can be calculated only at run time.
Currently the following approach is used to do so:
* bpf_object__open_buffer() to open Elf file from a buffer;
* bpf_object__find_map_by_name() to find relevant map;
* bpf_map__def() to get map attributes and create struct bpf_create_map_attr from them;
* update max_entries in bpf_create_map_attr;
* bpf_create_map_xattr() to create new map with updated max_entries;
* bpf_map__reuse_fd() to replace the map in bpf_object with newly created one.
And after all this bpf_object can finally be loaded. The map will have new size.
It 1) is quite a lot of steps; 2) doesn't take BTF into account.
For "2)" even more steps should be made and some of them require changes to libbpf (e.g. to get struct btf * from bpf_object).
Instead the whole problem can be solved by introducing simple bpf_map__resize() API that checks the map and sets new max_entries if the map is not loaded yet.
So the new steps are:
* bpf_object__open_buffer() to open Elf file from a buffer;
* bpf_object__find_map_by_name() to find relevant map;
* bpf_map__resize() to update max_entries.
That's much simpler and works with BTF.
--- tools/lib/bpf/libbpf.c | 14 ++++++++++++++ tools/lib/bpf/libbpf.h | 1 + tools/lib/bpf/libbpf.map | 1 + 3 files changed, 16 insertions(+)
tools/lib/bpf/libbpf.c +14 -0
@@ -1114,6 +1114,20 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd)return -errno; } +int bpf_map__resize (struct bpf_map *map,__u32 max_entries) +{ +if (!map || !max_entries) +return -EINVAL ; + +/* If map already created, its attributes can't be changed. */ +if (map->fd >=0 ) +return -EBUSY ; + + map->def.max_entries = max_entries; + +return 0 ; +} +static int bpf_object__probe_name (struct bpf_object *obj) {
tools/lib/bpf/libbpf.h +1 -0
@@ -294,6 +294,7 @@ LIBBPF_API int bpf_map__set_priv(struct bpf_map *map, void *priv, bpf_map_clear_priv_t clear_priv); LIBBPF_API void *bpf_map__priv(struct bpf_map *map); LIBBPF_API int bpf_map__reuse_fd(struct bpf_map *map, int fd); +LIBBPF_API int bpf_map__resize(struct bpf_map *map, __u32 max_entries); LIBBPF_API bool bpf_map__is_offload_neutral(struct bpf_map *map); LIBBPF_API void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex); LIBBPF_API int bpf_map__pin(struct bpf_map *map, const char *path);
tools/lib/bpf/libbpf.map +1 -0
@@ -130,6 +130,7 @@ LIBBPF_0.0.2 { bpf_probe_helper; bpf_probe_map_type; bpf_probe_prog_type; + bpf_map__resize; bpf_map_lookup_elem_flags; bpf_object__find_map_fd_by_name; bpf_get_link_xdp_id;
Signature · 1 line
2.17.1
Re: [PATCH bpf-next 1/2] libbpf: Introduce bpf_map__resize
Quoted 27 lines · Andrey Ignatov
Add
bpf_map__resize()to changemax_entriesfor a map.Quite often necessary map size is unknown at compile time and can be calculated only at run time.
Currently the following approach is used to do so:
*bpf_object__open_buffer()to open Elf file from a buffer;
*bpf_object__find_map_by_name()to find relevant map;
*bpf_map__def()to get map attributes and create structbpf_create_map_attrfrom them;
* updatemax_entriesinbpf_create_map_attr;
*bpf_create_map_xattr()to create new map with updatedmax_entries;
*bpf_map__reuse_fd()to replace the map inbpf_objectwith newly created one.And after all this
bpf_objectcan finally be loaded. The map will have new size.It 1) is quite a lot of steps; 2) doesn't take BTF into account.
For "2)" even more steps should be made and some of them require changes to libbpf (e.g. to get struct btf * from
bpf_object).Instead the whole problem can be solved by introducing simple
bpf_map__resize()API that checks the map and sets newmax_entriesif the map is not loaded yet.
Quoted 8 lines
So the new steps are:
*bpf_object__open_buffer()to open Elf file from a buffer;
*bpf_object__find_map_by_name()to find relevant map;
*bpf_map__resize()to updatemax_entries.That's much simpler and works with BTF.
Signed-off-by Andrey Ignatov <[email protected]>
PATCH 2/2 libbpf: Introduce bpf_object__btf
In reply to Andrey IgnatovAdd new accessor for bpf_object to get opaque struct btf * from it.
struct btf * is needed for all operations with BTF and it's present in bpf_object. The only thing missing is a way to get it.
Example use-case is to get BTF key_type_id an value_type_id for a map in bpf_object. It can be done with btf__get_map_kv_tids() but that function requires struct btf *.
Similar API can be added for struct btf_ext but no use-case for it yet.
--- tools/lib/bpf/libbpf.c | 5 +++++ tools/lib/bpf/libbpf.h | 3 +++ tools/lib/bpf/libbpf.map | 1 + 3 files changed, 9 insertions(+)
tools/lib/bpf/libbpf.c +5 -0
@@ -2332,6 +2332,11 @@ unsigned int bpf_object__kversion(struct bpf_object *obj)return obj ? obj->kern_version :0 ; } +struct btf *bpf_object__btf (struct bpf_object *obj) +{ +return obj ? obj->btf :NULL ; +} +int bpf_object__btf_fd (const struct bpf_object *obj) {return obj->btf ?btf__fd (obj->btf) :-1 ;
tools/lib/bpf/libbpf.h +3 -0
@@ -89,6 +89,9 @@ LIBBPF_API int bpf_object__load(struct bpf_object *obj); LIBBPF_API int bpf_object__unload(struct bpf_object *obj); LIBBPF_API const char *bpf_object__name(struct bpf_object *obj); LIBBPF_API unsigned int bpf_object__kversion(struct bpf_object *obj); + +struct btf ; +LIBBPF_API struct btf *bpf_object__btf(struct bpf_object *obj); LIBBPF_API int bpf_object__btf_fd(const struct bpf_object *obj); LIBBPF_API struct bpf_program *
tools/lib/bpf/libbpf.map +1 -0
@@ -132,6 +132,7 @@ LIBBPF_0.0.2 { bpf_probe_prog_type; bpf_map__resize; bpf_map_lookup_elem_flags; + bpf_object__btf; bpf_object__find_map_fd_by_name; bpf_get_link_xdp_id; btf__dedup;
Signature · 1 line
2.17.1
Re: [PATCH bpf-next 2/2] libbpf: Introduce bpf_object__btf
Quoted 6 lines · Andrey Ignatov
Add new accessor for
bpf_objectto get opaque struct btf * from it.struct btf * is needed for all operations with BTF and it's present in
bpf_object. The only thing missing is a way to get it.Example use-case is to get BTF
key_type_idanvalue_type_idfor a map in
nit: an => and
Quoted 6 lines
bpf_object. It can be done withbtf__get_map_kv_tids()but that function requires struct btf *.Similar API can be added for struct
btf_extbut no use-case for it yet.Signed-off-by Andrey Ignatov <[email protected]>
Daniel Borkmann
maintainerRe: [PATCH bpf-next 2/2] libbpf: Introduce bpf_object__btf
Quoted 10 lines · Yonghong Song
Quoted 6 lines · Andrey Ignatov
Add new accessor for
bpf_objectto get opaque struct btf * from it.struct btf * is needed for all operations with BTF and it's present in
bpf_object. The only thing missing is a way to get it.Example use-case is to get BTF
key_type_idanvalue_type_idfor a map innit: an => and
Quoted 2 lines
bpf_object. It can be done withbtf__get_map_kv_tids()but that function requires struct btf *.
Series applied and fixed above typo, thanks!