From: Bryce Kahle <git@brycekahle.com>
To: bpf@vger.kernel.org
Cc: quentin@isovalent.com, ast@kernel.org, daniel@iogearbox.net,
Bryce Kahle <bryce.kahle@datadoghq.com>
Subject: [PATCH bpf-next v4] bpftool: add support for split BTF to gen min_core_btf
Date: Tue, 30 Jan 2024 15:05:10 -0800 [thread overview]
Message-ID: <20240130230510.791-1-git@brycekahle.com> (raw)
From: Bryce Kahle <bryce.kahle@datadoghq.com>
Enables a user to generate minimized kernel module BTF.
If an eBPF program probes a function within a kernel module or uses
types that come from a kernel module, split BTF is required. The split
module BTF contains only the BTF types that are unique to the module.
It will reference the base/vmlinux BTF types and always starts its type
IDs at X+1 where X is the largest type ID in the base BTF.
Minimization allows a user to ship only the types necessary to do
relocations for the program(s) in the provided eBPF object file(s). A
minimized module BTF will still not contain vmlinux BTF types, so you
should always minimize the vmlinux file first, and then minimize the
kernel module file.
Example:
bpftool gen min_core_btf vmlinux.btf vm-min.btf prog.bpf.o
bpftool -B vm-min.btf gen min_core_btf mod.btf mod-min.btf prog.bpf.o
v3->v4:
- address style nit about start_id initialization
- rename base to src_base_btf (base_btf is a global var)
- copy src_base_btf so new BTF is not modifying original vmlinux BTF
Signed-off-by: Bryce Kahle <bryce.kahle@datadoghq.com>
---
.../bpf/bpftool/Documentation/bpftool-gen.rst | 18 ++++++++++-
tools/bpf/bpftool/gen.c | 32 +++++++++++++++----
2 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/tools/bpf/bpftool/Documentation/bpftool-gen.rst b/tools/bpf/bpftool/Documentation/bpftool-gen.rst
index 5006e724d..e067d3b05 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-gen.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-gen.rst
@@ -16,7 +16,7 @@ SYNOPSIS
**bpftool** [*OPTIONS*] **gen** *COMMAND*
- *OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } }
+ *OPTIONS* := { |COMMON_OPTIONS| | { **-B** | **--base-btf** } | { **-L** | **--use-loader** } }
*COMMAND* := { **object** | **skeleton** | **help** }
@@ -202,6 +202,14 @@ OPTIONS
=======
.. include:: common_options.rst
+ -B, --base-btf *FILE*
+ Pass a base BTF object. Base BTF objects are typically used
+ with BTF objects for kernel modules. To avoid duplicating
+ all kernel symbols required by modules, BTF objects for
+ modules are "split", they are built incrementally on top of
+ the kernel (vmlinux) BTF object. So the base BTF reference
+ should usually point to the kernel BTF.
+
-L, --use-loader
For skeletons, generate a "light" skeleton (also known as "loader"
skeleton). A light skeleton contains a loader eBPF program. It does
@@ -444,3 +452,11 @@ ones given to min_core_btf.
obj = bpf_object__open_file("one.bpf.o", &opts);
...
+
+Kernel module BTF may also be minimized by using the -B option:
+
+**$ bpftool -B 5.4.0-smaller.btf gen min_core_btf 5.4.0-module.btf 5.4.0-module-smaller.btf one.bpf.o**
+
+A minimized module BTF will still not contain vmlinux BTF types, so you
+should always minimize the vmlinux file first, and then minimize the
+kernel module file.
diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c
index ee3ce2b80..57691f766 100644
--- a/tools/bpf/bpftool/gen.c
+++ b/tools/bpf/bpftool/gen.c
@@ -1630,6 +1630,7 @@ static int do_help(int argc, char **argv)
" %1$s %2$s help\n"
"\n"
" " HELP_SPEC_OPTIONS " |\n"
+ " {-B|--base-btf} |\n"
" {-L|--use-loader} }\n"
"",
bin_name, "gen");
@@ -1695,14 +1696,14 @@ btfgen_new_info(const char *targ_btf_path)
if (!info)
return NULL;
- info->src_btf = btf__parse(targ_btf_path, NULL);
+ info->src_btf = btf__parse_split(targ_btf_path, base_btf);
if (!info->src_btf) {
err = -errno;
p_err("failed parsing '%s' BTF file: %s", targ_btf_path, strerror(errno));
goto err_out;
}
- info->marked_btf = btf__parse(targ_btf_path, NULL);
+ info->marked_btf = btf__parse_split(targ_btf_path, base_btf);
if (!info->marked_btf) {
err = -errno;
p_err("failed parsing '%s' BTF file: %s", targ_btf_path, strerror(errno));
@@ -2139,12 +2140,29 @@ static int btfgen_remap_id(__u32 *type_id, void *ctx)
/* Generate BTF from relocation information previously recorded */
static struct btf *btfgen_get_btf(struct btfgen_info *info)
{
- struct btf *btf_new = NULL;
+ struct btf *btf_new = NULL, *src_base_btf_new = NULL;
unsigned int *ids = NULL;
+ const struct btf *src_base_btf;
unsigned int i, n = btf__type_cnt(info->marked_btf);
- int err = 0;
+ int start_id, err = 0;
+
+ src_base_btf = btf__base_btf(info->src_btf);
+ start_id = src_base_btf ? btf__type_cnt(src_base_btf) : 1;
- btf_new = btf__new_empty();
+ /* clone BTF to sanitize a copy and leave the original intact */
+ if (src_base_btf) {
+ const void *raw_data;
+ __u32 sz;
+
+ raw_data = btf__raw_data(src_base_btf, &sz);
+ src_base_btf_new = btf__new(raw_data, sz);
+ if (!src_base_btf_new) {
+ err = -errno;
+ goto err_out;
+ }
+ }
+
+ btf_new = btf__new_empty_split(src_base_btf_new);
if (!btf_new) {
err = -errno;
goto err_out;
@@ -2157,7 +2175,7 @@ static struct btf *btfgen_get_btf(struct btfgen_info *info)
}
/* first pass: add all marked types to btf_new and add their new ids to the ids map */
- for (i = 1; i < n; i++) {
+ for (i = start_id; i < n; i++) {
const struct btf_type *cloned_type, *type;
const char *name;
int new_id;
@@ -2213,7 +2231,7 @@ static struct btf *btfgen_get_btf(struct btfgen_info *info)
}
/* second pass: fix up type ids */
- for (i = 1; i < btf__type_cnt(btf_new); i++) {
+ for (i = start_id; i < btf__type_cnt(btf_new); i++) {
struct btf_type *btf_type = (struct btf_type *) btf__type_by_id(btf_new, i);
err = btf_type_visit_type_ids(btf_type, btfgen_remap_id, ids);
--
2.25.1
next reply other threads:[~2024-01-30 23:05 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-30 23:05 Bryce Kahle [this message]
2024-01-31 18:13 ` [PATCH bpf-next v4] bpftool: add support for split BTF to gen min_core_btf Alan Maguire
2024-02-02 22:16 ` Andrii Nakryiko
2024-02-06 10:59 ` Alan Maguire
2024-02-08 0:26 ` Andrii Nakryiko
2024-02-08 22:45 ` Alan Maguire
2024-02-09 19:50 ` Andrii Nakryiko
2024-02-01 0:54 ` Quentin Monnet
2024-02-01 21:05 ` Bryce Kahle
2024-02-02 22:10 ` Andrii Nakryiko
2024-02-03 0:58 ` Bryce Kahle
2024-02-05 18:21 ` Andrii Nakryiko
2024-02-07 18:51 ` Bryce Kahle
2024-02-07 22:38 ` Yonghong Song
2024-02-08 0:30 ` Andrii Nakryiko
2024-02-08 1:56 ` Yonghong Song
2024-02-08 23:01 ` Alan Maguire
2024-02-09 19:58 ` Andrii Nakryiko
2024-02-26 21:48 ` Bryce Kahle
2024-02-29 0:59 ` Andrii Nakryiko
2024-02-29 15:24 ` Quentin Monnet
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=20240130230510.791-1-git@brycekahle.com \
--to=git@brycekahle.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=bryce.kahle@datadoghq.com \
--cc=daniel@iogearbox.net \
--cc=quentin@isovalent.com \
/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.