231 lines
7.8 KiB
ReStructuredText
231 lines
7.8 KiB
ReStructuredText
|
==================
|
||
|
BPF Selftest Notes
|
||
|
==================
|
||
|
General instructions on running selftests can be found in
|
||
|
`Documentation/bpf/bpf_devel_QA.rst`__.
|
||
|
|
||
|
__ /Documentation/bpf/bpf_devel_QA.rst#q-how-to-run-bpf-selftests
|
||
|
|
||
|
=========================
|
||
|
Running Selftests in a VM
|
||
|
=========================
|
||
|
|
||
|
It's now possible to run the selftests using ``tools/testing/selftests/bpf/vmtest.sh``.
|
||
|
The script tries to ensure that the tests are run with the same environment as they
|
||
|
would be run post-submit in the CI used by the Maintainers.
|
||
|
|
||
|
This script downloads a suitable Kconfig and VM userspace image from the system used by
|
||
|
the CI. It builds the kernel (without overwriting your existing Kconfig), recompiles the
|
||
|
bpf selftests, runs them (by default ``tools/testing/selftests/bpf/test_progs``) and
|
||
|
saves the resulting output (by default in ``~/.bpf_selftests``).
|
||
|
|
||
|
Script dependencies:
|
||
|
- clang (preferably built from sources, https://github.com/llvm/llvm-project);
|
||
|
- pahole (preferably built from sources, https://git.kernel.org/pub/scm/devel/pahole/pahole.git/);
|
||
|
- qemu;
|
||
|
- docutils (for ``rst2man``);
|
||
|
- libcap-devel.
|
||
|
|
||
|
For more information on about using the script, run:
|
||
|
|
||
|
.. code-block:: console
|
||
|
|
||
|
$ tools/testing/selftests/bpf/vmtest.sh -h
|
||
|
|
||
|
.. note:: The script uses pahole and clang based on host environment setting.
|
||
|
If you want to change pahole and llvm, you can change `PATH` environment
|
||
|
variable in the beginning of script.
|
||
|
|
||
|
.. note:: The script currently only supports x86_64.
|
||
|
|
||
|
Additional information about selftest failures are
|
||
|
documented here.
|
||
|
|
||
|
profiler[23] test failures with clang/llvm <12.0.0
|
||
|
==================================================
|
||
|
|
||
|
With clang/llvm <12.0.0, the profiler[23] test may fail.
|
||
|
The symptom looks like
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
// r9 is a pointer to map_value
|
||
|
// r7 is a scalar
|
||
|
17: bf 96 00 00 00 00 00 00 r6 = r9
|
||
|
18: 0f 76 00 00 00 00 00 00 r6 += r7
|
||
|
math between map_value pointer and register with unbounded min value is not allowed
|
||
|
|
||
|
// the instructions below will not be seen in the verifier log
|
||
|
19: a5 07 01 00 01 01 00 00 if r7 < 257 goto +1
|
||
|
20: bf 96 00 00 00 00 00 00 r6 = r9
|
||
|
// r6 is used here
|
||
|
|
||
|
The verifier will reject such code with above error.
|
||
|
At insn 18 the r7 is indeed unbounded. The later insn 19 checks the bounds and
|
||
|
the insn 20 undoes map_value addition. It is currently impossible for the
|
||
|
verifier to understand such speculative pointer arithmetic.
|
||
|
Hence `this patch`__ addresses it on the compiler side. It was committed on llvm 12.
|
||
|
|
||
|
__ https://reviews.llvm.org/D85570
|
||
|
|
||
|
The corresponding C code
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
for (int i = 0; i < MAX_CGROUPS_PATH_DEPTH; i++) {
|
||
|
filepart_length = bpf_probe_read_str(payload, ...);
|
||
|
if (filepart_length <= MAX_PATH) {
|
||
|
barrier_var(filepart_length); // workaround
|
||
|
payload += filepart_length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bpf_iter test failures with clang/llvm 10.0.0
|
||
|
=============================================
|
||
|
|
||
|
With clang/llvm 10.0.0, the following two bpf_iter tests failed:
|
||
|
* ``bpf_iter/ipv6_route``
|
||
|
* ``bpf_iter/netlink``
|
||
|
|
||
|
The symptom for ``bpf_iter/ipv6_route`` looks like
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
2: (79) r8 = *(u64 *)(r1 +8)
|
||
|
...
|
||
|
14: (bf) r2 = r8
|
||
|
15: (0f) r2 += r1
|
||
|
; BPF_SEQ_PRINTF(seq, "%pi6 %02x ", &rt->fib6_dst.addr, rt->fib6_dst.plen);
|
||
|
16: (7b) *(u64 *)(r8 +64) = r2
|
||
|
only read is supported
|
||
|
|
||
|
The symptom for ``bpf_iter/netlink`` looks like
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
; struct netlink_sock *nlk = ctx->sk;
|
||
|
2: (79) r7 = *(u64 *)(r1 +8)
|
||
|
...
|
||
|
15: (bf) r2 = r7
|
||
|
16: (0f) r2 += r1
|
||
|
; BPF_SEQ_PRINTF(seq, "%pK %-3d ", s, s->sk_protocol);
|
||
|
17: (7b) *(u64 *)(r7 +0) = r2
|
||
|
only read is supported
|
||
|
|
||
|
This is due to a llvm BPF backend bug. `The fix`__
|
||
|
has been pushed to llvm 10.x release branch and will be
|
||
|
available in 10.0.1. The patch is available in llvm 11.0.0 trunk.
|
||
|
|
||
|
__ https://reviews.llvm.org/D78466
|
||
|
|
||
|
bpf_verif_scale/loop6.o test failure with Clang 12
|
||
|
==================================================
|
||
|
|
||
|
With Clang 12, the following bpf_verif_scale test failed:
|
||
|
* ``bpf_verif_scale/loop6.o``
|
||
|
|
||
|
The verifier output looks like
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
R1 type=ctx expected=fp
|
||
|
The sequence of 8193 jumps is too complex.
|
||
|
|
||
|
The reason is compiler generating the following code
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
; for (i = 0; (i < VIRTIO_MAX_SGS) && (i < num); i++) {
|
||
|
14: 16 05 40 00 00 00 00 00 if w5 == 0 goto +64 <LBB0_6>
|
||
|
15: bc 51 00 00 00 00 00 00 w1 = w5
|
||
|
16: 04 01 00 00 ff ff ff ff w1 += -1
|
||
|
17: 67 05 00 00 20 00 00 00 r5 <<= 32
|
||
|
18: 77 05 00 00 20 00 00 00 r5 >>= 32
|
||
|
19: a6 01 01 00 05 00 00 00 if w1 < 5 goto +1 <LBB0_4>
|
||
|
20: b7 05 00 00 06 00 00 00 r5 = 6
|
||
|
00000000000000a8 <LBB0_4>:
|
||
|
21: b7 02 00 00 00 00 00 00 r2 = 0
|
||
|
22: b7 01 00 00 00 00 00 00 r1 = 0
|
||
|
; for (i = 0; (i < VIRTIO_MAX_SGS) && (i < num); i++) {
|
||
|
23: 7b 1a e0 ff 00 00 00 00 *(u64 *)(r10 - 32) = r1
|
||
|
24: 7b 5a c0 ff 00 00 00 00 *(u64 *)(r10 - 64) = r5
|
||
|
|
||
|
Note that insn #15 has w1 = w5 and w1 is refined later but
|
||
|
r5(w5) is eventually saved on stack at insn #24 for later use.
|
||
|
This cause later verifier failure. The bug has been `fixed`__ in
|
||
|
Clang 13.
|
||
|
|
||
|
__ https://reviews.llvm.org/D97479
|
||
|
|
||
|
BPF CO-RE-based tests and Clang version
|
||
|
=======================================
|
||
|
|
||
|
A set of selftests use BPF target-specific built-ins, which might require
|
||
|
bleeding-edge Clang versions (Clang 12 nightly at this time).
|
||
|
|
||
|
Few sub-tests of core_reloc test suit (part of test_progs test runner) require
|
||
|
the following built-ins, listed with corresponding Clang diffs introducing
|
||
|
them to Clang/LLVM. These sub-tests are going to be skipped if Clang is too
|
||
|
old to support them, they shouldn't cause build failures or runtime test
|
||
|
failures:
|
||
|
|
||
|
- __builtin_btf_type_id() [0_, 1_, 2_];
|
||
|
- __builtin_preserve_type_info(), __builtin_preserve_enum_value() [3_, 4_].
|
||
|
|
||
|
.. _0: https://reviews.llvm.org/D74572
|
||
|
.. _1: https://reviews.llvm.org/D74668
|
||
|
.. _2: https://reviews.llvm.org/D85174
|
||
|
.. _3: https://reviews.llvm.org/D83878
|
||
|
.. _4: https://reviews.llvm.org/D83242
|
||
|
|
||
|
Floating-point tests and Clang version
|
||
|
======================================
|
||
|
|
||
|
Certain selftests, e.g. core_reloc, require support for the floating-point
|
||
|
types, which was introduced in `Clang 13`__. The older Clang versions will
|
||
|
either crash when compiling these tests, or generate an incorrect BTF.
|
||
|
|
||
|
__ https://reviews.llvm.org/D83289
|
||
|
|
||
|
Kernel function call test and Clang version
|
||
|
===========================================
|
||
|
|
||
|
Some selftests (e.g. kfunc_call and bpf_tcp_ca) require a LLVM support
|
||
|
to generate extern function in BTF. It was introduced in `Clang 13`__.
|
||
|
|
||
|
Without it, the error from compiling bpf selftests looks like:
|
||
|
|
||
|
.. code-block:: console
|
||
|
|
||
|
libbpf: failed to find BTF for extern 'tcp_slow_start' [25] section: -2
|
||
|
|
||
|
__ https://reviews.llvm.org/D93563
|
||
|
|
||
|
Clang dependencies for static linking tests
|
||
|
===========================================
|
||
|
|
||
|
linked_vars, linked_maps, and linked_funcs tests depend on `Clang fix`__ to
|
||
|
generate valid BTF information for weak variables. Please make sure you use
|
||
|
Clang that contains the fix.
|
||
|
|
||
|
__ https://reviews.llvm.org/D100362
|
||
|
|
||
|
Clang relocation changes
|
||
|
========================
|
||
|
|
||
|
Clang 13 patch `clang reloc patch`_ made some changes on relocations such
|
||
|
that existing relocation types are broken into more types and
|
||
|
each new type corresponds to only one way to resolve relocation.
|
||
|
See `kernel llvm reloc`_ for more explanation and some examples.
|
||
|
Using clang 13 to compile old libbpf which has static linker support,
|
||
|
there will be a compilation failure::
|
||
|
|
||
|
libbpf: ELF relo #0 in section #6 has unexpected type 2 in .../bpf_tcp_nogpl.o
|
||
|
|
||
|
Here, ``type 2`` refers to new relocation type ``R_BPF_64_ABS64``.
|
||
|
To fix this issue, user newer libbpf.
|
||
|
|
||
|
.. Links
|
||
|
.. _clang reloc patch: https://reviews.llvm.org/D102712
|
||
|
.. _kernel llvm reloc: /Documentation/bpf/llvm_reloc.rst
|