On Tue, Jul 6, 2021 at 10:24 AM Martynas Pumputis <m@xxxxxxxxx> wrote: > > When loading a BPF program with a pinned map, the loader checks whether > the pinned map can be reused, i.e. their properties match. To derive > such of the pinned map, the loader invokes BPF_OBJ_GET_INFO_BY_FD and > then does the comparison. > > Unfortunately, on < 4.12 kernels the BPF_OBJ_GET_INFO_BY_FD is not > available, so loading the program fails with the following error: > > libbpf: failed to get map info for map FD 5: Invalid argument > libbpf: couldn't reuse pinned map at > '/sys/fs/bpf/tc/globals/cilium_call_policy': parameter > mismatch" > libbpf: map 'cilium_call_policy': error reusing pinned map > libbpf: map 'cilium_call_policy': failed to create: > Invalid argument(-22) > libbpf: failed to load object 'bpf_overlay.o' > > To fix this, probe the kernel for BPF_OBJ_GET_INFO_BY_FD support. If it > doesn't support, then fallback to derivation of the map properties via > /proc/$PID/fdinfo/$MAP_FD. > > Signed-off-by: Martynas Pumputis <m@xxxxxxxxx> > --- > tools/lib/bpf/libbpf.c | 103 +++++++++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 92 insertions(+), 11 deletions(-) > [...] > @@ -4406,10 +4478,19 @@ static bool map_is_reuse_compat(const struct bpf_map *map, int map_fd) > > map_info_len = sizeof(map_info); > > - if (bpf_obj_get_info_by_fd(map_fd, &map_info, &map_info_len)) { > - pr_warn("failed to get map info for map FD %d: %s\n", > - map_fd, libbpf_strerror_r(errno, msg, sizeof(msg))); > - return false; > + if (kernel_supports(obj, FEAT_OBJ_GET_INFO_BY_FD)) { why not just try bpf_obj_get_info_by_fd() first, and if it fails always fallback to bpf_get_map_info_from_fdinfo(). No need to do feature detection. This will cut down on the amount of code without any regression in behavior. More so, it will actually now be consistent and good behavior in case of bpf_map__reuse_fd() where we don't have obj. WDYT? > + if (bpf_obj_get_info_by_fd(map_fd, &map_info, &map_info_len)) { > + pr_warn("failed to get map info for map FD %d: %s\n", > + map_fd, > + libbpf_strerror_r(errno, msg, sizeof(msg))); > + return false; > + } [...]