From: Alan Maguire <alan.maguire@oracle.com>
To: Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, ast@fb.com,
daniel@iogearbox.net, kernel-team@fb.com,
Alan Maguire <alan.maguire@oracle.com>
Subject: Re: [PATCH bpf-next] libbpf: support module BTF for BPF_TYPE_ID_TARGET CO-RE relocation
Date: Sun, 6 Dec 2020 00:37:49 +0000 (GMT) [thread overview]
Message-ID: <alpine.LRH.2.23.451.2012060025520.1505@localhost> (raw)
In-Reply-To: <20201205025140.443115-1-andrii@kernel.org>
On Fri, 4 Dec 2020, Andrii Nakryiko wrote:
> When Clang emits ldimm64 instruction for BPF_TYPE_ID_TARGET CO-RE relocation,
> put module BTF FD, containing target type, into upper 32 bits of imm64.
>
> Because this FD is internal to libbpf, it's very cumbersome to test this in
> selftests. Manual testing was performed with debug log messages sprinkled
> across selftests and libbpf, confirming expected values are substituted.
> Better testing will be performed as part of the work adding module BTF types
> support to bpf_snprintf_btf() helpers.
>
> Cc: Alan Maguire <alan.maguire@oracle.com>
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Thanks so much for doing this Andrii! When I tested, I ran into a problem;
it turns out when a module struct such as "veth_stats" is used, it's
classified as BTF_KIND_FWD, and as a result when we iterate over
the modules and look in the veth module, "struct veth_stats" does not
match since its module kind (BTF_KIND_STRUCT) does not match the candidate
kind (BTF_KIND_FWD). I'm kind of out of my depth here, but the below
patch (on top of your patch) worked. However without it - when we find
0 candidate matches - as well as not substituting the module object
id/type id - we hit a segfault:
Program terminated with signal 11, Segmentation fault.
#0 0x0000000000480bf9 in bpf_core_calc_relo (prog=0x4d6ba40,
relo=0x4d70e7c,
relo_idx=0, local_spec=0x7ffe2cf17b00, targ_spec=0x0,
res=0x7ffe2cf17ae0)
at libbpf.c:4408
4408 switch (kind) {
Missing separate debuginfos, use: debuginfo-install
elfutils-libelf-0.172-2.el7.x86_64 glibc-2.17-196.el7.x86_64
libattr-2.4.46-13.el7.x86_64 libcap-2.22-9.el7.x86_64
libgcc-4.8.5-36.0.1.el7_6.2.x86_64 zlib-1.2.7-18.el7.x86_64
(gdb) bt
#0 0x0000000000480bf9 in bpf_core_calc_relo (prog=0x4d6ba40,
relo=0x4d70e7c,
relo_idx=0, local_spec=0x7ffe2cf17b00, targ_spec=0x0,
res=0x7ffe2cf17ae0)
at libbpf.c:4408
The dereferences of targ_spec in bpf_core_recalc_relo() seem
to be the cause; that function is called with a NULL targ_spec
when 0 candidates are found, so it's possible we'd need to
guard those accesses for cases where a bogus type was passed
in and no candidates were found. If the below looks good would
it make sense to roll it into your patch or will I add it to my
v3 patch series?
Thanks again for your help with this!
Alan
From 08040730dbff6c5d7636927777ac85a71c10827f Mon Sep 17 00:00:00 2001
From: Alan Maguire <alan.maguire@oracle.com>
Date: Sun, 6 Dec 2020 01:10:28 +0100
Subject: [PATCH] libbpf: handle fwd kinds when checking candidate relocations
for modules
when a struct belonging to a module is being assessed, it will be
designated a fwd kind (BTF_KIND_FWD); when matching candidate
types constraints on exact type matching need to be relaxed to
ensure that such structures are found successfully. Introduce
kinds_match() function to handle this comparison.
Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
---
tools/lib/bpf/libbpf.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 539956f..00fdb30 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -4673,6 +4673,24 @@ static void bpf_core_free_cands(struct core_cand_list *cands)
free(cands);
}
+/* module-specific structs will have relo kind set to fwd, so as
+ * well as handling exact matches, struct has to match fwd kind.
+ */
+static bool kinds_match(const struct btf_type *type1,
+ const struct btf_type *type2)
+{
+ __u8 kind1 = btf_kind(type1);
+ __u8 kind2 = btf_kind(type2);
+
+ if (kind1 == kind2)
+ return true;
+ if (kind1 == BTF_KIND_STRUCT && kind2 == BTF_KIND_FWD)
+ return true;
+ if (kind1 == BTF_KIND_FWD && kind2 == BTF_KIND_STRUCT)
+ return true;
+ return false;
+}
+
static int bpf_core_add_cands(struct core_cand *local_cand,
size_t local_essent_len,
const struct btf *targ_btf,
@@ -4689,7 +4707,7 @@ static int bpf_core_add_cands(struct core_cand *local_cand,
n = btf__get_nr_types(targ_btf);
for (i = targ_start_id; i <= n; i++) {
t = btf__type_by_id(targ_btf, i);
- if (btf_kind(t) != btf_kind(local_cand->t))
+ if (!kinds_match(t, local_cand->t))
continue;
targ_name = btf__name_by_offset(targ_btf, t->name_off);
@@ -5057,7 +5075,7 @@ static int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id
/* caller made sure that names match (ignoring flavor suffix) */
local_type = btf__type_by_id(local_btf, local_id);
targ_type = btf__type_by_id(targ_btf, targ_id);
- if (btf_kind(local_type) != btf_kind(targ_type))
+ if (!kinds_match(local_type, targ_type))
return 0;
recur:
@@ -5070,7 +5088,7 @@ static int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id
if (!local_type || !targ_type)
return -EINVAL;
- if (btf_kind(local_type) != btf_kind(targ_type))
+ if (!kinds_match(local_type, targ_type))
return 0;
switch (btf_kind(local_type)) {
--
1.8.3.1
next prev parent reply other threads:[~2020-12-06 0:39 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-05 2:51 [PATCH bpf-next] libbpf: support module BTF for BPF_TYPE_ID_TARGET CO-RE relocation Andrii Nakryiko
2020-12-06 0:37 ` Alan Maguire [this message]
2020-12-08 3:28 ` Andrii Nakryiko
2020-12-08 22:02 ` Alan Maguire
2020-12-07 16:38 ` Alan Maguire
2020-12-08 3:12 ` Alexei Starovoitov
2020-12-08 3:40 ` Andrii Nakryiko
2020-12-08 22:13 ` Alan Maguire
2020-12-08 23:39 ` Alexei Starovoitov
2020-12-09 23:21 ` Alan Maguire
2020-12-15 22:38 ` one prog multi fentry. Was: " Alexei Starovoitov
2020-12-16 16:18 ` Alan Maguire
2020-12-16 22:27 ` Andrii Nakryiko
2020-12-17 7:16 ` Alexei Starovoitov
2020-12-17 17:46 ` Alan Maguire
2020-12-17 18:22 ` Alexei Starovoitov
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=alpine.LRH.2.23.451.2012060025520.1505@localhost \
--to=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=ast@fb.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=netdev@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).