[PATCH bpf-next] docs/bpf: Add description of .BTF.base section

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Now that .BTF.base sections are generated for out-of-tree kernel
modules (provided pahole supports the "distilled_base" BTF feature),
document .BTF.base and its role in supporting resilient split BTF
and BTF relocation.

Signed-off-by: Alan Maguire <alan.maguire@xxxxxxxxxx>
---
 Documentation/bpf/btf.rst | 78 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/Documentation/bpf/btf.rst b/Documentation/bpf/btf.rst
index 93060283b6fd..57992a9aa4f6 100644
--- a/Documentation/bpf/btf.rst
+++ b/Documentation/bpf/btf.rst
@@ -835,7 +835,7 @@ section named by ``btf_ext_info_sec->sec_name_off``.
 See :ref:`Documentation/bpf/llvm_reloc.rst <btf-co-re-relocations>`
 for more information on CO-RE relocations.
 
-4.2 .BTF_ids section
+4.3 .BTF_ids section
 --------------------
 
 The .BTF_ids section encodes BTF ID values that are used within the kernel.
@@ -896,6 +896,82 @@ and is used as a filter when resolving the BTF ID value.
 All the BTF ID lists and sets are compiled in the .BTF_ids section and
 resolved during the linking phase of kernel build by ``resolve_btfids`` tool.
 
+4.4 .BTF.base section
+---------------------
+Split BTF - where the .BTF section only contains types not in the associated
+base .BTF section - is an extremely efficient way to encode type information
+for kernel modules, since they generally consist of a few module-specific
+types along with a large set of shared kernel types.  The former are encoded
+in split BTF, while the latter are encoded in base BTF, resulting in more
+compact representations.  A type in split BTF that referes to a type in
+base BTF refers to it using its base type id, and split BTF type ids start
+at last_base_type + 1.
+
+The downside of this approach however is that this makes the split BTF
+somewhat brittle - when the base BTF changes, these base id references are
+no longer valid and the split BTF itself becomes useless.  The role of the
+.BTF.base section is to make split BTF more resilient for cases where
+the base BTF may change, as is the case for kernel modules not built every
+time the kernel is for example.  .BTF.base contains named base types; INTs,
+FLOATs, STRUCTs, UNIONs, ENUM[64]s and FWDs.  INTs and FLOATs are fully
+described in .BTF.base sections, while composite types like structs
+and unions are not fully defined - the .BTF.base type simply serves as
+a description of the type the split BTF referred to, so struct/unions
+has 0 members in the .BTF.base section.  ENUM[64]s are similarly recorded
+with 0 members.  Any other types are added to the split BTF.  This
+distillation process then leaves us with a .BTF.base section with
+such minimal descriptions of base types and .BTF split section which refers
+to those base types.  Later, we can relocate the split BTF using both the
+information stored in the .BTF.base section and the new BTF base; the type
+information in the .BTF.base section allows us to update the split BTF
+references to point at the corresponding new base BTF types.
+
+BTF relocation happens on kernel module load when a kernel module has a
+.BTF.base section, and libbpf also provides a btf__relocate() API to
+accomplish this.
+
+As an example consider the following base BTF:
+
+[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
+[2] STRUCT 'foo' size=8 vlen=2
+        'f1' type_id=1 bits_offset=0
+        'f2' type_id=2 bits_offset=32
+
+...and associated split BTF:
+
+[3] PTR '(anon)' type_id=2
+
+i.e. split BTF describes a pointer to struct foo { int f1; int f2 };
+
+.BTF.base will consist of
+
+[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
+[2] STRUCT 'foo' size=8 vlen=0
+
+..so if we relocate the split BTF later using the following new base
+BTF:
+
+[1] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none)
+[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
+[3] STRUCT 'foo' size=8 vlen=2
+        'f1' type_id=2 bits_offset=0
+        'f2' type_id=2 bits_offset=32
+
+...we can use our .BTF.base description to know that the split BTF reference
+is to struct foo, and relocation results in:
+
+[4] PTR '(anon)' type_id=3
+
+Note that we had to update type id and start BTF id for the split BTF.
+
+So we see how .BTF.base plays the role of facilitating later relocation,
+leading to more resilient split BTF.
+
+.BTF.base sections will be generated automatically for out-of-tree kernel module
+builds - i.e. where KBUILD_EXTMOD is set (as it would be for "make M=path/2/mod"
+cases).  .BTF.base generation requires pahole support for the "distilled_base"
+BTF feature; this is available in pahole v1.28 and later.
+
 5. Using BTF
 ============
 
-- 
2.43.5





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux