Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> writes: > On Fri, Nov 8, 2019 at 1:33 PM Toke Høiland-Jørgensen <toke@xxxxxxxxxx> wrote: >> >> From: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> >> >> Since the automatic map-pinning happens during load, it will leave pinned >> maps around if the load fails at a later stage. Fix this by unpinning any >> pinned maps on cleanup. To avoid unpinning pinned maps that were reused >> rather than newly pinned, add a new boolean property on struct bpf_map to >> keep track of whether that map was reused or not; and only unpin those maps >> that were not reused. >> >> Fixes: 57a00f41644f ("libbpf: Add auto-pinning of maps when loading BPF objects") >> Acked-by: Song Liu <songliubraving@xxxxxx> >> Signed-off-by: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> >> --- >> tools/lib/bpf/libbpf.c | 16 +++++++++++++--- >> 1 file changed, 13 insertions(+), 3 deletions(-) >> >> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c >> index be4af95d5a2c..cea61b2ec9d3 100644 >> --- a/tools/lib/bpf/libbpf.c >> +++ b/tools/lib/bpf/libbpf.c >> @@ -229,6 +229,7 @@ struct bpf_map { >> enum libbpf_map_type libbpf_type; >> char *pin_path; >> bool pinned; >> + bool was_reused; > > nit: just reused, similar to pinned? > >> }; >> >> struct bpf_secdata { >> @@ -1995,6 +1996,7 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd) >> map->def.map_flags = info.map_flags; >> map->btf_key_type_id = info.btf_key_type_id; >> map->btf_value_type_id = info.btf_value_type_id; >> + map->was_reused = true; >> >> return 0; >> >> @@ -4007,15 +4009,18 @@ bpf_object__open_buffer(const void *obj_buf, size_t obj_buf_sz, >> return bpf_object__open_mem(obj_buf, obj_buf_sz, &opts); >> } >> >> -int bpf_object__unload(struct bpf_object *obj) >> +static int __bpf_object__unload(struct bpf_object *obj, bool unpin) >> { >> size_t i; >> >> if (!obj) >> return -EINVAL; >> >> - for (i = 0; i < obj->nr_maps; i++) >> + for (i = 0; i < obj->nr_maps; i++) { >> zclose(obj->maps[i].fd); >> + if (unpin && obj->maps[i].pinned && !obj->maps[i].was_reused) >> + bpf_map__unpin(&obj->maps[i], NULL); >> + } >> >> for (i = 0; i < obj->nr_programs; i++) >> bpf_program__unload(&obj->programs[i]); >> @@ -4023,6 +4028,11 @@ int bpf_object__unload(struct bpf_object *obj) >> return 0; >> } >> >> +int bpf_object__unload(struct bpf_object *obj) >> +{ >> + return __bpf_object__unload(obj, false); >> +} >> + >> int bpf_object__load_xattr(struct bpf_object_load_attr *attr) >> { >> struct bpf_object *obj; >> @@ -4047,7 +4057,7 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) >> >> return 0; >> out: >> - bpf_object__unload(obj); >> + __bpf_object__unload(obj, true); > > giving this is the only (special) case of auto-unpinning auto-pinned > maps, why not do a trivial loop here, instead of having this extra > unpin flag and extra __bpf_object__unload function? Oh, you mean just do a loop in addition to the call to __unload? Sure, I guess we can do that instead... -Toke