In order to enable the older kernel to use the CO-RE feature, load the
vmlinux btf of the specified path.
Learn from Andrii's comments in [0], add the custom_btf_path parameter
to bpf_obj_open_opts, you can directly use the skeleton's
<objname>_bpf__open_opts function to pass in the custom_btf_path
parameter.
Prior to this, there was also a developer who provided a patch with
similar functions. It is a pity that the follow-up did not continue to
advance. See [1].
[0]https://lore.kernel.org/bpf/CAEf4BzbJZLjNoiK8_VfeVg_Vrg=9iYFv+po-38SMe=UzwDKJ=Q@mail.gmail.com/#t
[1]https://yhbt.net/lore/all/CAEf4Bzbgw49w2PtowsrzKQNcxD4fZRE6AKByX-5-dMo-+oWHHA@mail.gmail.com/
Signed-off-by: Shuyi Cheng <redacted>
---
tools/lib/bpf/libbpf.c | 23 ++++++++++++++++++++---
tools/lib/bpf/libbpf.h | 6 +++++-
2 files changed, 25 insertions(+), 4 deletions(-)
@@ -94,8 +94,12 @@ struct bpf_object_open_opts {*systemKconfigforCONFIG_xxxexterns.*/constchar*kconfig;+/* Specify the path of vmlinux btf to facilitate the use of CO-RE features+*intheoldkernel.+*/+char*custom_btf_path;};-#define bpf_object_open_opts__last_field kconfig+#define bpf_object_open_opts__last_field custom_btf_pathLIBBPF_APIstructbpf_object*bpf_object__open(constchar*path);LIBBPF_APIstructbpf_object*
From: Daniel Borkmann <daniel@iogearbox.net> Date: 2021-06-24 15:06:58
On 6/24/21 6:03 AM, Shuyi Cheng wrote:
quoted hunk
In order to enable the older kernel to use the CO-RE feature, load the
vmlinux btf of the specified path.
Learn from Andrii's comments in [0], add the custom_btf_path parameter
to bpf_obj_open_opts, you can directly use the skeleton's
<objname>_bpf__open_opts function to pass in the custom_btf_path
parameter.
Prior to this, there was also a developer who provided a patch with
similar functions. It is a pity that the follow-up did not continue to
advance. See [1].
[0]https://lore.kernel.org/bpf/CAEf4BzbJZLjNoiK8_VfeVg_Vrg=9iYFv+po-38SMe=UzwDKJ=Q@mail.gmail.com/#t
[1]https://yhbt.net/lore/all/CAEf4Bzbgw49w2PtowsrzKQNcxD4fZRE6AKByX-5-dMo-+oWHHA@mail.gmail.com/
Signed-off-by: Shuyi Cheng <redacted>
---
tools/lib/bpf/libbpf.c | 23 ++++++++++++++++++++---
tools/lib/bpf/libbpf.h | 6 +++++-
2 files changed, 25 insertions(+), 4 deletions(-)
nit: This should rather go to the 'Parse and load BTF vmlinux if any of [...]'
section of struct bpf_object, and for consistency, I'd keep the btf_ prefix,
like: char *btf_custom_path
@@ -4394,7 +4394,7 @@ static int btf_dedup_remap_types(struct btf_dedup *d)*Probefewwell-knownlocationsforvmlinuxkernelimageandtrytoloadBTF*dataoutofittousefortargetBTF.*/-structbtf*libbpf_find_kernel_btf(void)+staticstructbtf*__libbpf_find_kernel_btf(char*btf_custom_path){struct{constchar*path_fmt;
@@ -4402,6 +4402,8 @@ struct btf *libbpf_find_kernel_btf(void)}locations[]={/* try canonical vmlinux BTF through sysfs first */{"/sys/kernel/btf/vmlinux",true/* raw BTF */},+/* try user defined vmlinux ELF if a path was specified */+{btf_custom_path},/* fall back to trying to find vmlinux ELF on disk otherwise */{"/boot/vmlinux-%1$s"},{"/lib/modules/%1$s/vmlinux-%1$s"},
@@ -94,8 +94,12 @@ struct bpf_object_open_opts {*systemKconfigforCONFIG_xxxexterns.*/constchar*kconfig;+/* Specify the path of vmlinux btf to facilitate the use of CO-RE features+*intheoldkernel.+*/+char*custom_btf_path;};-#define bpf_object_open_opts__last_field kconfig+#define bpf_object_open_opts__last_field custom_btf_pathLIBBPF_APIstructbpf_object*bpf_object__open(constchar*path);LIBBPF_APIstructbpf_object*
In order to enable the older kernel to use the CO-RE feature, load the
vmlinux btf of the specified path.
Learn from Andrii's comments in [0], add the custom_btf_path parameter
to bpf_obj_open_opts, you can directly use the skeleton's
<objname>_bpf__open_opts function to pass in the custom_btf_path
parameter.
Prior to this, there was also a developer who provided a patch with
similar functions. It is a pity that the follow-up did not continue to
advance. See [1].
[0]https://lore.kernel.org/bpf/CAEf4BzbJZLjNoiK8_VfeVg_Vrg=9iYFv+po-38SMe=UzwDKJ=Q@mail.gmail.com/#t
[1]https://yhbt.net/lore/all/CAEf4Bzbgw49w2PtowsrzKQNcxD4fZRE6AKByX-5-dMo-+oWHHA@mail.gmail.com/
Signed-off-by: Shuyi Cheng <redacted>
---
tools/lib/bpf/libbpf.c | 23 ++++++++++++++++++++---
tools/lib/bpf/libbpf.h | 6 +++++-
2 files changed, 25 insertions(+), 4 deletions(-)
nit: This should rather go to the 'Parse and load BTF vmlinux if any of
[...]'
section of struct bpf_object, and for consistency, I'd keep the btf_
prefix,
like: char *btf_custom_path
Couldn't we do something like (only compile-tested):
Your approach is very inspiring to me. But I did it for two reasons.
1. When the developer specifies btf_custom_path, btf should only be
loaded from btf_custom_path;
2. Now pahole supports saving vmlinux's btf in raw format, so the old
kernel can provide btf in elf format or raw format. see [0].
[0]
https://git.kernel.org/pub/scm/devel/pahole/pahole.git/tree/pahole.c#n1157
What do you think?
Regards,
Shuyi
@@ -4394,7 +4394,7 @@ static int btf_dedup_remap_types(struct btf_dedup *d)*Probefewwell-knownlocationsforvmlinuxkernelimageandtryto
load BTF
* data out of it to use for target BTF.
*/
-struct btf *libbpf_find_kernel_btf(void)
+static struct btf *__libbpf_find_kernel_btf(char *btf_custom_path)
{
struct {
const char *path_fmt;
@@ -4402,6 +4402,8 @@ struct btf *libbpf_find_kernel_btf(void) } locations[] = { /* try canonical vmlinux BTF through sysfs first */ { "/sys/kernel/btf/vmlinux", true /* raw BTF */ },+ /* try user defined vmlinux ELF if a path was specified */+ { btf_custom_path }, /* fall back to trying to find vmlinux ELF on disk otherwise */ { "/boot/vmlinux-%1$s" }, { "/lib/modules/%1$s/vmlinux-%1$s" },
@@ -4419,11 +4421,11 @@ struct btf *libbpf_find_kernel_btf(void) uname(&buf); for (i = 0; i < ARRAY_SIZE(locations); i++) {+ if (!locations[i].path_fmt)+ continue; snprintf(path, PATH_MAX, locations[i].path_fmt, buf.release);- if (access(path, R_OK)) continue;- if (locations[i].raw_btf) btf = btf__parse_raw(path); else
visit, void *ctx)
{
int i, n, err;
And then you just call it as:
obj->btf_vmlinux = __libbpf_find_kernel_btf(obj->btf_custom_path);
err = libbpf_get_error(obj->btf_vmlinux);
On Wed, Jun 23, 2021 at 9:04 PM Shuyi Cheng
[off-list ref] wrote:
quoted hunk
In order to enable the older kernel to use the CO-RE feature, load the
vmlinux btf of the specified path.
Learn from Andrii's comments in [0], add the custom_btf_path parameter
to bpf_obj_open_opts, you can directly use the skeleton's
<objname>_bpf__open_opts function to pass in the custom_btf_path
parameter.
Prior to this, there was also a developer who provided a patch with
similar functions. It is a pity that the follow-up did not continue to
advance. See [1].
[0]https://lore.kernel.org/bpf/CAEf4BzbJZLjNoiK8_VfeVg_Vrg=9iYFv+po-38SMe=UzwDKJ=Q@mail.gmail.com/#t
[1]https://yhbt.net/lore/all/CAEf4Bzbgw49w2PtowsrzKQNcxD4fZRE6AKByX-5-dMo-+oWHHA@mail.gmail.com/
Signed-off-by: Shuyi Cheng <redacted>
---
tools/lib/bpf/libbpf.c | 23 ++++++++++++++++++++---
tools/lib/bpf/libbpf.h | 6 +++++-
2 files changed, 25 insertions(+), 4 deletions(-)
I think it will be more flexible to treat custom_btf as an vmlinux BTF
override, just like [1] did. I can see how in some situations users
might want to treat this custom BTF as either a replacement of vmlinux
BTF or as an augmentation of vmlinux BTF for the purpose of extra
custom CO-RE relocations (e.g., something along the XDP hints that
were discussed recently). For now it's probably enough to implement
"custom BTF is a replacement for vmlinux BTF" policy and, if
necessary, add "custom BTF is in addition to vmlinux BTF" later with
extra opts flag/field.
Keep in mind that this custom BTF is only useful for BPF CO-RE
relocation. Any other kernel feature relying on vmlinux BTF (e.g.,
fentry) won't work with custom BTF because it expects correct BTF type
IDs.
if strlen() is >= PATH_MAX you'll just silently ignore it? We should
either truncate silently (because PATH_MAX is totally reasonable
assumption) or error out.
quoted hunk
+ obj->custom_btf_path = strdup(tmp_btf_path);
+ if (!obj->custom_btf_path)
+ return ERR_PTR(-ENOMEM);
+ }
kconfig = OPTS_GET(opts, kconfig, NULL);
if (kconfig) {
@@ -8702,6 +8718,7 @@ void bpf_object__close(struct bpf_object *obj) for (i = 0; i < obj->nr_maps; i++) bpf_map__destroy(&obj->maps[i]);+ zfree(&obj->custom_btf_path); zfree(&obj->kconfig); zfree(&obj->externs); obj->nr_extern = 0;
@@ -94,8 +94,12 @@ struct bpf_object_open_opts {*systemKconfigforCONFIG_xxxexterns.*/constchar*kconfig;+/* Specify the path of vmlinux btf to facilitate the use of CO-RE features+*intheoldkernel.+*/+char*custom_btf_path;};-#define bpf_object_open_opts__last_field kconfig+#define bpf_object_open_opts__last_field custom_btf_pathLIBBPF_APIstructbpf_object*bpf_object__open(constchar*path);LIBBPF_APIstructbpf_object*--
On Thu, Jun 24, 2021 at 8:06 AM Daniel Borkmann [off-list ref] wrote:
On 6/24/21 6:03 AM, Shuyi Cheng wrote:
quoted
In order to enable the older kernel to use the CO-RE feature, load the
vmlinux btf of the specified path.
Learn from Andrii's comments in [0], add the custom_btf_path parameter
to bpf_obj_open_opts, you can directly use the skeleton's
<objname>_bpf__open_opts function to pass in the custom_btf_path
parameter.
Prior to this, there was also a developer who provided a patch with
similar functions. It is a pity that the follow-up did not continue to
advance. See [1].
[0]https://lore.kernel.org/bpf/CAEf4BzbJZLjNoiK8_VfeVg_Vrg=9iYFv+po-38SMe=UzwDKJ=Q@mail.gmail.com/#t
[1]https://yhbt.net/lore/all/CAEf4Bzbgw49w2PtowsrzKQNcxD4fZRE6AKByX-5-dMo-+oWHHA@mail.gmail.com/
Signed-off-by: Shuyi Cheng <redacted>
---
tools/lib/bpf/libbpf.c | 23 ++++++++++++++++++++---
tools/lib/bpf/libbpf.h | 6 +++++-
2 files changed, 25 insertions(+), 4 deletions(-)
nit: This should rather go to the 'Parse and load BTF vmlinux if any of [...]'
section of struct bpf_object, and for consistency, I'd keep the btf_ prefix,
like: char *btf_custom_path
Couldn't we do something like (only compile-tested):
I wonder what are the benefits of this approach, though. My
expectation is that if the user specifies a custom BTF path and BTF is
missing then the whole bpf_object load process should fail, but in
this case it will be silently ignored. Also, if custom BTF is
specified, that custom BTF has to be used even if
/sys/kernel/btf/vmlinux is present, but the patch below will still
prefer /sys/kernel/btf/vmlinux.
So the semantics is different. I'm not saying it's wrong, but I think
it means we need to discuss what behavior we are after first.
On Wed, Jun 23, 2021 at 9:04 PM Shuyi Cheng
[off-list ref] wrote:
quoted
In order to enable the older kernel to use the CO-RE feature, load the
vmlinux btf of the specified path.
Learn from Andrii's comments in [0], add the custom_btf_path parameter
to bpf_obj_open_opts, you can directly use the skeleton's
<objname>_bpf__open_opts function to pass in the custom_btf_path
parameter.
Prior to this, there was also a developer who provided a patch with
similar functions. It is a pity that the follow-up did not continue to
advance. See [1].
[0]https://lore.kernel.org/bpf/CAEf4BzbJZLjNoiK8_VfeVg_Vrg=9iYFv+po-38SMe=UzwDKJ=Q@mail.gmail.com/#t
[1]https://yhbt.net/lore/all/CAEf4Bzbgw49w2PtowsrzKQNcxD4fZRE6AKByX-5-dMo-+oWHHA@mail.gmail.com/
Signed-off-by: Shuyi Cheng <redacted>
---
tools/lib/bpf/libbpf.c | 23 ++++++++++++++++++++---
tools/lib/bpf/libbpf.h | 6 +++++-
2 files changed, 25 insertions(+), 4 deletions(-)
I think it will be more flexible to treat custom_btf as an vmlinux BTF
override, just like [1] did. I can see how in some situations users
might want to treat this custom BTF as either a replacement of vmlinux
BTF or as an augmentation of vmlinux BTF for the purpose of extra
custom CO-RE relocations (e.g., something along the XDP hints that
were discussed recently). For now it's probably enough to implement
"custom BTF is a replacement for vmlinux BTF" policy and, if
necessary, add "custom BTF is in addition to vmlinux BTF" later with
extra opts flag/field.
Thank you very much for your reply.
So this part of the code remains the same, right?
Keep in mind that this custom BTF is only useful for BPF CO-RE
relocation. Any other kernel feature relying on vmlinux BTF (e.g.,
fentry) won't work with custom BTF because it expects correct BTF type
IDs.
if strlen() is >= PATH_MAX you'll just silently ignore it? We should
either truncate silently (because PATH_MAX is totally reasonable
assumption) or error out.
Agree. I will send the second version of the patch.
Regards,
Shuyi
quoted
+ obj->custom_btf_path = strdup(tmp_btf_path);
+ if (!obj->custom_btf_path)
+ return ERR_PTR(-ENOMEM);
+ }
kconfig = OPTS_GET(opts, kconfig, NULL);
if (kconfig) {
@@ -8702,6 +8718,7 @@ void bpf_object__close(struct bpf_object *obj) for (i = 0; i < obj->nr_maps; i++) bpf_map__destroy(&obj->maps[i]);+ zfree(&obj->custom_btf_path); zfree(&obj->kconfig); zfree(&obj->externs); obj->nr_extern = 0;
@@ -94,8 +94,12 @@ struct bpf_object_open_opts {*systemKconfigforCONFIG_xxxexterns.*/constchar*kconfig;+/* Specify the path of vmlinux btf to facilitate the use of CO-RE features+*intheoldkernel.+*/+char*custom_btf_path;};-#define bpf_object_open_opts__last_field kconfig+#define bpf_object_open_opts__last_field custom_btf_pathLIBBPF_APIstructbpf_object*bpf_object__open(constchar*path);LIBBPF_APIstructbpf_object*--