From: Martynas Pumputis <m@lambda.lt>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: bpf <bpf@vger.kernel.org>, Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>
Subject: Re: [PATCH bpf] libbpf: fix reuse of pinned map on older kernel
Date: Thu, 8 Jul 2021 13:45:32 +0200 [thread overview]
Message-ID: <41795594-5d66-e17e-095c-cc4cdc84a017@lambda.lt> (raw)
In-Reply-To: <CAEf4BzbCAO=hjA=hSh9QXN3C79xOmM0=Cc0H1gZnhm6LdDz9Sw@mail.gmail.com>
On 7/8/21 12:58 AM, Andrii Nakryiko wrote:
> On Tue, Jul 6, 2021 at 10:24 AM Martynas Pumputis <m@lambda.lt> 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@lambda.lt>
>> ---
>> 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?
I was thinking about it, but then decided to use the kernel probing
instead. The reasoning was the following:
1) For programs with many pinned maps we would issue many failing
BPF_OBJ_GET_INFO_BY_FD calls (instead of a single one) which might
hinder the performance.
2) A canonical way in libbpf to detect features is via kernel_supports()
and friends, so I didn't want to diverge there.
Re bpf_map__reuse_fd(), if we are OK to break the API before libbpf
v1.0, then we could extend bpf_map__reuse_fd() to accept the obj.
However, this would break some consumers of the lib, e.g., iproute2 [1].
Anyway, if you think that we can ignore 1) and 2), then I'm happy to
change. Also, I'm going to submit to bpf-next.
[1]:
https://github.com/shemminger/iproute2/blob/v5.11.0/lib/bpf_libbpf.c#L98
>
>
>> + 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;
>> + }
>
> [...]
>
next prev parent reply other threads:[~2021-07-08 11:43 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-06 17:26 [PATCH bpf] libbpf: fix reuse of pinned map on older kernel Martynas Pumputis
2021-07-06 23:32 ` Song Liu
2021-07-07 10:38 ` Martynas Pumputis
2021-07-07 22:55 ` Andrii Nakryiko
2021-07-07 22:58 ` Andrii Nakryiko
2021-07-08 11:45 ` Martynas Pumputis [this message]
2021-07-08 15:01 ` Toke Høiland-Jørgensen
2021-07-08 20:20 ` Andrii Nakryiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=41795594-5d66-e17e-095c-cc4cdc84a017@lambda.lt \
--to=m@lambda.lt \
--cc=andrii.nakryiko@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.