요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=================================
HOWTO interact with BPF subsystem
=================================
This document provides information for the BPF subsystem about various
workflows related to reporting bugs, submitting patches, and queueing
patches for stable kernels.
For general information about submitting patches, please refer to
Documentation/process/submitting-patches.rst. This document only describes
additional specifics related to BPF.
.. contents::
:local:
:depth: 2
Reporting bugs
==============
Q: How do I report bugs for BPF kernel code?
--------------------------------------------
A: Since all BPF kernel development as well as bpftool and iproute2 BPF
loader development happens through the bpf kernel mailing list,
please report any found issues around BPF to the following mailing
list:
bpf@vger.kernel.org
This may also include issues related to XDP, BPF tracing, etc.
Given netdev has a high volume of traffic, please also add the BPF
maintainers to Cc (from kernel ``MAINTAINERS`` file):
* Alexei Starovoitov <ast@kernel.org>
* Daniel Borkmann <daniel@iogearbox.net>
In case a buggy commit has already been identified, make sure to keep
the actual commit authors in Cc as well for the report. They can
typically be identified through the kernel's git tree.
**Please do NOT report BPF issues to bugzilla.kernel.org since it
is a guarantee that the reported issue will be overlooked.**
Submitting patches
==================
Q: How do I run BPF CI on my changes before sending them out for review?
------------------------------------------------------------------------
A: BPF CI is GitHub based and hosted at https://github.com/kernel-patches/bpf.
While GitHub also provides a CLI that can be used to accomplish the same
results, here we focus on the UI based workflow.
The following steps lay out how to start a CI run for your patches:
- Create a fork of the aforementioned repository in your own account (one time
action)
- Clone the fork locally, check out a new branch tracking either the bpf-next
or bpf branch, and apply your to-be-tested patches on top of it
- Push the local branch to your fork and create a pull request against
kernel-patches/bpf's bpf-next_base or bpf_base branch, respectively
Shortly after the pull request has been created, the CI workflow will run. Note
that capacity is shared with patches submitted upstream being checked and so
depending on utilization the run can take a while to finish.
Note furthermore that both base branches (bpf-next_base and bpf_base) will be
updated as patches are pushed to the respective upstream branches they track. As
such, your patch set will automatically (be attempted to) be rebased as well.
This behavior can result in a CI run being aborted and restarted with the new
base line.
Q: To which mailing list do I need to submit my BPF patches?
------------------------------------------------------------
A: Please submit your BPF patches to the bpf kernel mailing list:
bpf@vger.kernel.org
In case your patch has changes in various different subsystems (e.g.
networking, tracing, security, etc), make sure to Cc the related kernel mailing
lists and maintainers from there as well, so they are able to review
the changes and provide their Acked-by's to the patches.
Q: Where can I find patches currently under discussion for BPF subsystem?
-------------------------------------------------------------------------
A: All patches that are Cc'ed to netdev are queued for review under netdev
patchwork project:
https://patchwork.kernel.org/project/netdevbpf/list/
Those patches which target BPF, are assigned to a 'bpf' delegate for
further processing from BPF maintainers. The current queue with
patches under review can be found at:
https://patchwork.kernel.org/project/netdevbpf/list/?delegate=121173
Once the patches have been reviewed by the BPF community as a whole
and approved by the BPF maintainers, their status in patchwork will be
changed to 'Accepted' and the submitter will be notified by mail. This
means that the patches look good from a BPF perspective and have been
applied to one of the two BPF kernel trees.
In case feedback from the community requires a respin of the patches,
their status in patchwork will be set to 'Changes Requested', and purged
from the current review queue. Likewise for cases where patches would
get rejected or are not applicable to the BPF trees (but assigned to
the 'bpf' delegate).
Q: How do the changes make their way into Linux?
------------------------------------------------
A: There are two BPF kernel trees (git repositories). Once patches have
been accepted by the BPF maintainers, they will be applied to one
of the two BPF trees:
* https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/
* https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/
The bpf tree itself is for fixes only, whereas bpf-next for features,
cleanups or other kind of improvements ("next-like" content). This is
analogous to net and net-next trees for networking. Both bpf and
bpf-next will only have a master branch in order to simplify against
which branch patches should get rebased to.
Accumulated BPF patches in the bpf tree will regularly get pulled
into the net kernel tree. Likewise, accumulated BPF patches accepted
into the bpf-next tree will make their way into net-next tree. net and
net-next are both run by David S. Miller. From there, they will go
into the kernel mainline tree run by Linus Torvalds. To read up on the
process of net and net-next being merged into the mainline tree, see
the documentation on netdev subsystem at
Documentation/process/maintainer-netdev.rst.
Occasionally, to prevent merge conflicts, we might send pull requests
to other trees (e.g. tracing) with a small subset of the patches, but
net and net-next are always the main trees targeted for integration.
The pull requests will contain a high-level summary of the accumulated
patches and can be searched on netdev kernel mailing list through the
following subject lines (``yyyy-mm-dd`` is the date of the pull
request)::
pull-request: bpf yyyy-mm-dd
pull-request: bpf-next yyyy-mm-dd
Q: How do I indicate which tree (bpf vs. bpf-next) my patch should be applied to?
---------------------------------------------------------------------------------
A: The process is the very same as described in the netdev subsystem
documentation at Documentation/process/maintainer-netdev.rst,
so please read up on it. The subject line must indicate whether the
patch is a fix or rather "next-like" content in order to let the
maintainers know whether it is targeted at bpf or bpf-next.
For fixes eventually landing in bpf -> net tree, the subject must
look like::
git format-patch --subject-prefix='PATCH bpf' start..finish
For features/improvements/etc that should eventually land in
bpf-next -> net-next, the subject must look like::
git format-patch --subject-prefix='PATCH bpf-next' start..finish
If unsure whether the patch or patch series should go into bpf
or net directly, or bpf-next or net-next directly, it is not a
problem either if the subject line says net or net-next as target.
It is eventually up to the maintainers to do the delegation of
the patches.
If it is clear that patches should go into bpf or bpf-next tree,
please make sure to rebase the patches against those trees in
order to reduce potential conflicts.
In case the patch or patch series has to be reworked and sent out
again in a second or later revision, it is also required to add a
version number (``v2``, ``v3``, ...) into the subject prefix::
git format-patch --subject-prefix='PATCH bpf-next v2' start..finish
When changes have been requested to the patch series, always send the
whole patch series again with the feedback incorporated (never send
individual diffs on top of the old series).
Q: What does it mean when a patch gets applied to bpf or bpf-next tree?
-----------------------------------------------------------------------
A: It means that the patch looks good for mainline inclusion from
a BPF point of view.
Be aware that this is not a final verdict that the patch will
automatically get accepted into net or net-next trees eventually:
On the bpf kernel mailing list reviews can come in at any point
in time. If discussions around a patch conclude that they cannot
get included as-is, we will either apply a follow-up fix or drop
them from the trees entirely. Therefore, we also reserve to rebase
the trees when deemed necessary. After all, the purpose of the tree
is to:
i) accumulate and stage BPF patches for integration into trees
like net and net-next, and
ii) run extensive BPF test suite and
workloads on the patches before they make their way any further.
Once the BPF pull request was accepted by David S. Miller, then
the patches end up in net or net-next tree, respectively, and
make their way from there further into mainline. Again, see the
documentation for netdev subsystem at
Documentation/process/maintainer-netdev.rst for additional information
e.g. on how often they are merged to mainline.
Q: How long do I need to wait for feedback on my BPF patches?
-------------------------------------------------------------
A: We try to keep the latency low. The usual time to feedback will
be around 2 or 3 business days. It may vary depending on the
complexity of changes and current patch load.
Q: How often do you send pull requests to major kernel trees like net or net-next?
----------------------------------------------------------------------------------
A: Pull requests will be sent out rather often in order to not
accumulate too many patches in bpf or bpf-next.
As a rule of thumb, expect pull requests for each tree regularly
at the end of the week. In some cases pull requests could additionally
come also in the middle of the week depending on the current patch
load or urgency.
Q: Are patches applied to bpf-next when the merge window is open?
-----------------------------------------------------------------
A: For the time when the merge window is open, bpf-next will not be
processed. This is roughly analogous to net-next patch processing,
so feel free to read up on the netdev docs at
Documentation/process/maintainer-netdev.rst about further details.
During those two weeks of merge window, we might ask you to resend
your patch series once bpf-next is open again. Once Linus released
a ``v*-rc1`` after the merge window, we continue processing of bpf-next.
For non-subscribers to kernel mailing lists, there is also a status
page run by David S. Miller on net-next that provides guidance:
http://vger.kernel.org/~davem/net-next.html
Q: Verifier changes and test cases
----------------------------------
Q: I made a BPF verifier change, do I need to add test cases for
BPF kernel selftests_?
A: If the patch has changes to the behavior of the verifier, then yes,
it is absolutely necessary to add test cases to the BPF kernel
selftests_ suite. If they are not present and we think they are
needed, then we might ask for them before accepting any changes.
In particular, test_verifier.c is tracking a high number of BPF test
cases, including a lot of corner cases that LLVM BPF back end may
generate out of the restricted C code. Thus, adding test cases is
absolutely crucial to make sure future changes do not accidentally
affect prior use-cases. Thus, treat those test cases as: verifier
behavior that is not tracked in test_verifier.c could potentially
be subject to change.
Q: samples/bpf preference vs selftests?
---------------------------------------
Q: When should I add code to ``samples/bpf/`` and when to BPF kernel
selftests_?
A: In general, we prefer additions to BPF kernel selftests_ rather than
``samples/bpf/``. The rationale is very simple: kernel selftests are
regularly run by various bots to test for kernel regressions.
The more test cases we add to BPF selftests, the better the coverage
and the less likely it is that those could accidentally break. It is
not that BPF kernel selftests cannot demo how a specific feature can
be used.
That said, ``samples/bpf/`` may be a good place for people to get started,
so it might be advisable that simple demos of features could go into
``samples/bpf/``, but advanced functional and corner-case testing rather
into kernel selftests.
If your sample looks like a test case, then go for BPF kernel selftests
instead!
Q: When should I add code to the bpftool?
-----------------------------------------
A: The main purpose of bpftool (under tools/bpf/bpftool/) is to provide
a central user space tool for debugging and introspection of BPF programs
and maps that are active in the kernel. If UAPI changes related to BPF
enable for dumping additional information of programs or maps, then
bpftool should be extended as well to support dumping them.
Q: When should I add code to iproute2's BPF loader?
---------------------------------------------------
A: For UAPI changes related to the XDP or tc layer (e.g. ``cls_bpf``),
the convention is that those control-path related changes are added to
iproute2's BPF loader as well from user space side. This is not only
useful to have UAPI changes properly designed to be usable, but also
to make those changes available to a wider user base of major
downstream distributions.
Q: Do you accept patches as well for iproute2's BPF loader?
-----------------------------------------------------------
A: Patches for the iproute2's BPF loader have to be sent to:
netdev@vger.kernel.org
While those patches are not processed by the BPF kernel maintainers,
please keep them in Cc as well, so they can be reviewed.
The official git repository for iproute2 is run by Stephen Hemminger
and can be found at:
https://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git/
The patches need to have a subject prefix of '``[PATCH iproute2
master]``' or '``[PATCH iproute2 net-next]``'. '``master``' or
'``net-next``' describes the target branch where the patch should be
applied to. Meaning, if kernel changes went into the net-next kernel
tree, then the related iproute2 changes need to go into the iproute2
net-next branch, otherwise they can be targeted at master branch. The
iproute2 net-next branch will get merged into the master branch after
the current iproute2 version from master has been released.
Like BPF, the patches end up in patchwork under the netdev project and
are delegated to 'shemminger' for further processing:
http://patchwork.ozlabs.org/project/netdev/list/?delegate=389
Q: What is the minimum requirement before I submit my BPF patches?
------------------------------------------------------------------
A: When submitting patches, always take the time and properly test your
patches *prior* to submission. Never rush them! If maintainers find
that your patches have not been properly tested, it is a good way to
get them grumpy. Testing patch submissions is a hard requirement!
Note, fixes that go to bpf tree *must* have a ``Fixes:`` tag included.
The same applies to fixes that target bpf-next, where the affected
commit is in net-next (or in some cases bpf-next). The ``Fixes:`` tag is
crucial in order to identify follow-up commits and tremendously helps
for people having to do backporting, so it is a must have!
We also don't accept patches with an empty commit message. Take your
time and properly write up a high quality commit message, it is
essential!
Think about it this way: other developers looking at your code a month
from now need to understand *why* a certain change has been done that
way, and whether there have been flaws in the analysis or assumptions
that the original author did. Thus providing a proper rationale and
describing the use-case for the changes is a must.
Patch submissions with >1 patch must have a cover letter which includes
a high level description of the series. This high level summary will
then be placed into the merge commit by the BPF maintainers such that
it is also accessible from the git log for future reference.
Q: Features changing BPF JIT and/or LLVM
----------------------------------------
Q: What do I need to consider when adding a new instruction or feature
that would require BPF JIT and/or LLVM integration as well?
A: We try hard to keep all BPF JITs up to date such that the same user
experience can be guaranteed when running BPF programs on different
architectures without having the program punt to the less efficient
interpreter in case the in-kernel BPF JIT is enabled.
If you are unable to implement or test the required JIT changes for
certain architectures, please work together with the related BPF JIT
developers in order to get the feature implemented in a timely manner.
Please refer to the git log (``arch/*/net/``) to locate the necessary
people for helping out.
Also always make sure to add BPF test cases (e.g. test_bpf.c and
test_verifier.c) for new instructions, so that they can receive
broad test coverage and help run-time testing the various BPF JITs.
In case of new BPF instructions, once the changes have been accepted
into the Linux kernel, please implement support into LLVM's BPF back
end. See LLVM_ section below for further information.
Q: What "BPF_INTERNAL" symbol namespace is for?
-----------------------------------------------
A: Symbols exported as BPF_INTERNAL can only be used by BPF infrastructure
like preload kernel modules with light skeleton. Most symbols outside
of BPF_INTERNAL are not expected to be used by code outside of BPF either.
Symbols may lack the designation because they predate the namespaces,
or due to an oversight.
Stable submission
=================
Q: I need a specific BPF commit in stable kernels. What should I do?
--------------------------------------------------------------------
A: In case you need a specific fix in stable kernels, first check whether
the commit has already been applied in the related ``linux-*.y`` branches:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/
If not the case, then drop an email to the BPF maintainers with the
netdev kernel mailing list in Cc and ask for the fix to be queued up:
netdev@vger.kernel.org
The process in general is the same as on netdev itself, see also the
the documentation on networking subsystem at
Documentation/process/maintainer-netdev.rst.
Q: Do you also backport to kernels not currently maintained as stable?
----------------------------------------------------------------------
A: No. If you need a specific BPF commit in kernels that are currently not
maintained by the stable maintainers, then you are on your own.
The current stable and longterm stable kernels are all listed here:
https://www.kernel.org/
Q: The BPF patch I am about to submit needs to go to stable as well
-------------------------------------------------------------------
What should I do?
A: The same rules apply as with netdev patch submissions in general, see
the netdev docs at Documentation/process/maintainer-netdev.rst.
Never add "``Cc: stable@vger.kernel.org``" to the patch description, but
ask the BPF maintainers to queue the patches instead. This can be done
with a note, for example, under the ``---`` part of the patch which does
not go into the git log. Alternatively, this can be done as a simple
request by mail instead.
Q: Queue stable patches
-----------------------
Q: Where do I find currently queued BPF patches that will be submitted
to stable?
A: Once patches that fix critical bugs got applied into the bpf tree, they
are queued up for stable submission under:
http://patchwork.ozlabs.org/bundle/bpf/stable/?state=*
They will be on hold there at minimum until the related commit made its
way into the mainline kernel tree.
After having been under broader exposure, the queued patches will be
submitted by the BPF maintainers to the stable maintainers.
Testing patches
===============
Q: How to run BPF selftests
---------------------------
A: After you have booted into the newly compiled kernel, navigate to
the BPF selftests_ suite in order to test BPF functionality (current
working directory points to the root of the cloned git tree)::
$ cd tools/testing/selftests/bpf/
$ make
To run the verifier tests::
$ sudo ./test_verifier
The verifier tests print out all the current checks being
performed. The summary at the end of running all tests will dump
information of test successes and failures::
Summary: 418 PASSED, 0 FAILED
In order to run through all BPF selftests, the following command is
needed::
$ sudo make run_tests
See :doc:`kernel selftest documentation </dev-tools/kselftest>`
for details.
To maximize the number of tests passing, the .config of the kernel
under test should match the config file fragment in
tools/testing/selftests/bpf as closely as possible.
Finally to ensure support for latest BPF Type Format features -
discussed in Documentation/bpf/btf.rst - pahole version 1.16
is required for kernels built with CONFIG_DEBUG_INFO_BTF=y.
pahole is delivered in the dwarves package or can be built
from source at
https://github.com/acmel/dwarves
pahole starts to use libbpf definitions and APIs since v1.13 after the
commit 21507cd3e97b ("pahole: add libbpf as submodule under lib/bpf").
It works well with the git repository because the libbpf submodule will
use "git submodule update --init --recursive" to update.
Unfortunately, the default github release source code does not contain
libbpf submodule source code and this will cause build issues, the tarball
from https://git.kernel.org/pub/scm/devel/pahole/pahole.git/ is same with
github, you can get the source tarball with corresponding libbpf submodule
codes from
https://fedorapeople.org/~acme/dwarves
Some distros have pahole version 1.16 packaged already, e.g.
Fedora, Gentoo.
Q: Which BPF kernel selftests version should I run my kernel against?
---------------------------------------------------------------------
A: If you run a kernel ``xyz``, then always run the BPF kernel selftests
from that kernel ``xyz`` as well. Do not expect that the BPF selftest
from the latest mainline tree will pass all the time.
In particular, test_bpf.c and test_verifier.c have a large number of
test cases and are constantly updated with new BPF test sequences, or
existing ones are adapted to verifier changes e.g. due to verifier
becoming smarter and being able to better track certain things.
LLVM
====
Q: Where do I find LLVM with BPF support?
-----------------------------------------
A: The BPF back end for LLVM is upstream in LLVM since version 3.7.1.
All major distributions these days ship LLVM with BPF back end enabled,
so for the majority of use-cases it is not required to compile LLVM by
hand anymore, just install the distribution provided package.
LLVM's static compiler lists the supported targets through
``llc --version``, make sure BPF targets are listed. Example::
$ llc --version
LLVM (http://llvm.org/):
LLVM version 10.0.0
Optimized build.
Default target: x86_64-unknown-linux-gnu
Host CPU: skylake
Registered Targets:
aarch64 - AArch64 (little endian)
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
For developers in order to utilize the latest features added to LLVM's
BPF back end, it is advisable to run the latest LLVM releases. Support
for new BPF kernel features such as additions to the BPF instruction
set are often developed together.
All LLVM releases can be found at: http://releases.llvm.org/
Q: Got it, so how do I build LLVM manually anyway?
--------------------------------------------------
A: We recommend that developers who want the fastest incremental builds
use the Ninja build system, you can find it in your system's package
manager, usually the package is ninja or ninja-build.
You need ninja, cmake and gcc-c++ as build requisites for LLVM. Once you
have that set up, proceed with building the latest LLVM and clang version
from the git repositories::
$ git clone https://github.com/llvm/llvm-project.git
$ mkdir -p llvm-project/llvm/build
$ cd llvm-project/llvm/build
$ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86" \
-DLLVM_ENABLE_PROJECTS="clang" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_BUILD_RUNTIME=OFF
$ ninja
The built binaries can then be found in the build/bin/ directory, where
you can point the PATH variable to.
Set ``-DLLVM_TARGETS_TO_BUILD`` equal to the target you wish to build, you
will find a full list of targets within the llvm-project/llvm/lib/Target
directory.
Q: Reporting LLVM BPF issues
----------------------------
Q: Should I notify BPF kernel maintainers about issues in LLVM's BPF code
generation back end or about LLVM generated code that the verifier
refuses to accept?
A: Yes, please do!
LLVM's BPF back end is a key piece of the whole BPF
infrastructure and it ties deeply into verification of programs from the
kernel side. Therefore, any issues on either side need to be investigated
and fixed whenever necessary.
Therefore, please make sure to bring them up at netdev kernel mailing
list and Cc BPF maintainers for LLVM and kernel bits:
* Yonghong Song <yhs@fb.com>
* Alexei Starovoitov <ast@kernel.org>
* Daniel Borkmann <daniel@iogearbox.net>
LLVM also has an issue tracker where BPF related bugs can be found:
https://bugs.llvm.org/buglist.cgi?quicksearch=bpf
However, it is better to reach out through mailing lists with having
maintainers in Cc.
Q: New BPF instruction for kernel and LLVM
------------------------------------------
Q: I have added a new BPF instruction to the kernel, how can I integrate
it into LLVM?
A: LLVM has a ``-mcpu`` selector for the BPF back end in order to allow
the selection of BPF instruction set extensions. Before llvm version 20,
the ``generic`` processor target is used, which is the base instruction
set (v1) of BPF. Since llvm 20, the default processor target has changed
to instruction set v3.
LLVM has an option to select ``-mcpu=probe`` where it will probe the host
kernel for supported BPF instruction set extensions and selects the
optimal set automatically.
For cross-compilation, a specific version can be select manually as well ::
$ llc -march bpf -mcpu=help
Available CPUs for this target:
generic - Select the generic processor.
probe - Select the probe processor.
v1 - Select the v1 processor.
v2 - Select the v2 processor.
[...]
Newly added BPF instructions to the Linux kernel need to follow the same
scheme, bump the instruction set version and implement probing for the
extensions such that ``-mcpu=probe`` users can benefit from the
optimization transparently when upgrading their kernels.
If you are unable to implement support for the newly added BPF instruction
please reach out to BPF developers for help.
By the way, the BPF kernel selftests run with ``-mcpu=probe`` for better
test coverage.
Q: clang flag for target bpf?
-----------------------------
Q: In some cases clang flag ``--target=bpf`` is used but in other cases the
default clang target, which matches the underlying architecture, is used.
What is the difference and when I should use which?
A: Although LLVM IR generation and optimization try to stay architecture
independent, ``--target=<arch>`` still has some impact on generated code:
- BPF program may recursively include header file(s) with file scope
inline assembly codes. The default target can handle this well,
while ``bpf`` target may fail if bpf backend assembler does not
understand these assembly codes, which is true in most cases.
- When compiled without ``-g``, additional elf sections, e.g.,
.eh_frame and .rela.eh_frame, may be present in the object file
with default target, but not with ``bpf`` target.
- The default target may turn a C switch statement into a switch table
lookup and jump operation. Since the switch table is placed
in the global readonly section, the bpf program will fail to load.
The bpf target does not support switch table optimization.
The clang option ``-fno-jump-tables`` can be used to disable
switch table generation.
- For clang ``--target=bpf``, it is guaranteed that pointer or long /
unsigned long types will always have a width of 64 bit, no matter
whether underlying clang binary or default target (or kernel) is
32 bit. However, when native clang target is used, then it will
compile these types based on the underlying architecture's conventions,
meaning in case of 32 bit architecture, pointer or long / unsigned
long types e.g. in BPF context structure will have width of 32 bit
while the BPF LLVM back end still operates in 64 bit. The native
target is mostly needed in tracing for the case of walking ``pt_regs``
or other kernel structures where CPU's register width matters.
Otherwise, ``clang --target=bpf`` is generally recommended.
You should use default target when:
- Your program includes a header file, e.g., ptrace.h, which eventually
pulls in some header files containing file scope host assembly codes.
- You can add ``-fno-jump-tables`` to work around the switch table issue.
Otherwise, you can use ``bpf`` target. Additionally, you *must* use bpf target
when:
- Your program uses data structures with pointer or long / unsigned long
types that interface with BPF helpers or context data structures. Access
into these structures is verified by the BPF verifier and may result
in verification failures if the native architecture is not aligned with
the BPF architecture, e.g. 64-bit. An example of this is
BPF_PROG_TYPE_SK_MSG require ``--target=bpf``
.. Links
.. _selftests:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/bpf/
Happy BPF hacking!
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
BPF subsystem 협업 안내
1-16이 문서는 BPF subsystem에서 bug를 report하고 patch를 제출하며 stable kernel용 patch를 queue하는 여러 workflow를 설명합니다.
일반적인 patch 제출 방법은 `Documentation/process/submitting-patches.rst`를 참조하십시오. 이 문서는 BPF에만 해당하는 추가 사항을 다룹니다.
BPF bug report
17-43질문: BPF kernel code의 bug는 어떻게 report합니까? 답변: BPF kernel 개발뿐 아니라 bpftool과 iproute2 BPF loader 개발도 모두 BPF kernel mailing list에서 이루어지므로, BPF와 관련해 발견한 문제는 `bpf@vger.kernel.org`로 report하십시오. XDP, BPF tracing 등에 관련된 문제도 여기에 포함됩니다.
netdev traffic 양이 많으므로 kernel `MAINTAINERS` file에 기재된 BPF maintainer도 Cc에 추가하십시오.
- Alexei Starovoitov <ast@kernel.org>
- Daniel Borkmann <daniel@iogearbox.net>
문제가 있는 commit을 이미 식별했다면 실제 commit author도 report의 Cc에 반드시 포함하십시오. 보통 kernel git tree에서 author를 찾을 수 있습니다.
BPF 문제를 `bugzilla.kernel.org`에 report하지 마십시오. 그곳에 올린 문제는 간과된다고 보아야 합니다.
Review 전 BPF CI 실행
44-73질문: 변경 사항을 review에 보내기 전에 BPF CI를 어떻게 실행합니까? 답변: BPF CI는 GitHub 기반이며 `https://github.com/kernel-patches/bpf`에서 운영됩니다. GitHub CLI로도 같은 결과를 얻을 수 있지만 여기서는 UI 기반 workflow를 설명합니다.
patch에 대한 CI run을 시작하는 절차는 다음과 같습니다.
- 앞서 언급한 repository를 자신의 account로 fork합니다. 이 작업은 한 번만 하면 됩니다.
- fork를 local에 clone하고 `bpf-next` 또는 `bpf` branch를 tracking하는 새 branch를 checkout한 뒤, test할 patch를 그 위에 적용합니다.
- local branch를 자신의 fork에 push하고 각각 `kernel-patches/bpf`의 `bpf-next_base` 또는 `bpf_base` branch를 대상으로 pull request를 만듭니다.
pull request를 만들면 곧 CI workflow가 실행됩니다. upstream에 제출된 patch 검사와 capacity를 공유하므로 사용량에 따라 완료까지 시간이 걸릴 수 있습니다.
`bpf-next_base`와 `bpf_base`는 tracking하는 upstream branch에 patch가 push될 때 갱신됩니다. 따라서 해당 patch set도 자동 rebase가 시도됩니다. 이 동작 때문에 CI run이 중단되고 새 baseline에서 다시 시작될 수 있습니다.
Mailing list와 patchwork
74-109질문: BPF patch를 어느 mailing list에 제출해야 합니까? 답변: BPF kernel mailing list인 `bpf@vger.kernel.org`에 제출하십시오.
patch가 networking, tracing, security 등 여러 subsystem을 변경한다면 관련 kernel mailing list와 maintainer도 Cc에 포함해야 합니다. 그래야 이들이 변경을 review하고 patch에 `Acked-by`를 제공할 수 있습니다.
질문: BPF subsystem에서 현재 논의 중인 patch는 어디에서 찾습니까? 답변: netdev에 Cc된 모든 patch는 netdev patchwork project인 `https://patchwork.kernel.org/project/netdevbpf/list/`에서 review queue에 들어갑니다.
BPF 대상 patch는 BPF maintainer가 처리하도록 `bpf` delegate에 할당됩니다. 현재 review 중인 queue는 `https://patchwork.kernel.org/project/netdevbpf/list/?delegate=121173`에서 확인할 수 있습니다.
BPF community 전체가 review하고 BPF maintainer가 승인하면 patchwork status가 `Accepted`로 바뀌고 제출자에게 mail이 전달됩니다. 이는 BPF 관점에서 patch가 적절하며 두 BPF kernel tree 중 하나에 적용됐다는 뜻입니다.
community feedback 때문에 patch를 다시 작성해야 하면 status는 `Changes Requested`가 되고 현재 review queue에서 제거됩니다. patch가 reject되거나 BPF tree에 적용할 수 없지만 `bpf` delegate에 할당된 경우도 마찬가지입니다.
BPF kernel tree와 mainline 경로
110-147질문: 변경 사항은 어떤 경로로 Linux에 들어갑니까? 답변: BPF maintainer가 patch를 accept하면 두 BPF kernel tree 중 하나에 적용합니다.
- https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/
- https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/
`bpf` tree는 fix 전용이며 `bpf-next`는 feature, cleanup, 그 밖의 improvement 같은 "next-like" content용입니다. networking의 `net`과 `net-next` 관계와 같습니다. rebase할 branch 선택을 단순화하기 위해 `bpf`와 `bpf-next`에는 모두 `master` branch만 있습니다.
`bpf`에 쌓인 patch는 정기적으로 `net` kernel tree로 pull되고, `bpf-next`에서 accept된 patch는 `net-next`로 이동합니다. David S. Miller가 `net`과 `net-next`를 모두 관리하며, 그 뒤 Linus Torvalds가 관리하는 kernel mainline tree로 들어갑니다. `net`과 `net-next`가 mainline에 merge되는 과정은 `Documentation/process/maintainer-netdev.rst`를 참조하십시오.
merge conflict를 막기 위해 가끔 patch 일부를 tracing 같은 다른 tree에 pull request로 보낼 수 있지만, 주된 integration 대상은 항상 `net`과 `net-next`입니다.
pull request에는 누적 patch의 high-level summary가 들어갑니다. `yyyy-mm-dd`가 pull request 날짜일 때 netdev kernel mailing list에서 다음 subject로 찾을 수 있습니다.
pull-request: bpf yyyy-mm-dd
pull-request: bpf-next yyyy-mm-dd
Target tree와 subject prefix
148-186질문: patch를 `bpf`와 `bpf-next` 중 어느 tree에 적용해야 하는지 어떻게 표시합니까? 답변: 절차는 `Documentation/process/maintainer-netdev.rst`의 netdev subsystem 설명과 같습니다. maintainer가 `bpf` 또는 `bpf-next` 대상을 알 수 있도록 subject line에 fix인지 "next-like" content인지 표시해야 합니다.
결국 `bpf -> net` tree로 들어갈 fix의 subject는 다음처럼 만듭니다.
git format-patch --subject-prefix='PATCH bpf' start..finish
`bpf-next -> net-next`로 들어갈 feature, improvement 등의 subject는 다음처럼 만듭니다.
git format-patch --subject-prefix='PATCH bpf-next' start..finish
patch 또는 series가 `bpf`와 `net` 중 어디로, 또는 `bpf-next`와 `net-next` 중 어디로 직접 가야 하는지 확실하지 않다면 subject line의 target을 `net`이나 `net-next`로 적어도 괜찮습니다. 최종 delegation은 maintainer가 결정합니다.
`bpf` 또는 `bpf-next`로 가야 함이 명확하면 잠재적 conflict를 줄이도록 해당 tree를 기준으로 patch를 rebase하십시오.
patch 또는 series를 수정해 두 번째 이상 revision으로 다시 보낼 때는 subject prefix에 `v2`, `v3` 같은 version number도 넣어야 합니다.
git format-patch --subject-prefix='PATCH bpf-next v2' start..finish
patch series에 변경 요청을 받았다면 feedback을 반영한 전체 series를 항상 다시 보내십시오. 이전 series 위에 개별 diff만 보내면 안 됩니다.
BPF tree 적용의 의미
187-214질문: patch가 `bpf` 또는 `bpf-next` tree에 적용됐다는 것은 무엇을 뜻합니까? 답변: BPF 관점에서 mainline inclusion에 적합해 보인다는 뜻입니다.
다만 patch가 결국 `net`이나 `net-next`에 자동으로 accept된다는 최종 판정은 아닙니다. BPF kernel mailing list에는 언제든 review가 들어올 수 있습니다. 논의 결과 patch를 그대로 포함할 수 없다면 follow-up fix를 적용하거나 tree에서 완전히 drop할 수 있으며, 필요하면 tree를 rebase할 수도 있습니다.
이 tree의 목적은 다음 두 가지입니다.
- BPF patch를 누적하고 stage해 `net`, `net-next` 같은 tree로 통합합니다.
- patch가 더 진행되기 전에 광범위한 BPF test suite와 workload를 실행합니다.
David S. Miller가 BPF pull request를 accept하면 patch는 각각 `net` 또는 `net-next` tree에 들어가고 그곳에서 mainline으로 진행합니다. mainline merge 주기 등 자세한 내용은 `Documentation/process/maintainer-netdev.rst`를 다시 참조하십시오.
Feedback 주기와 merge window
215-247질문: BPF patch feedback을 얼마나 기다려야 합니까? 답변: latency를 낮게 유지하려 하며 보통 영업일 기준 2~3일 안에 feedback을 줍니다. 변경 복잡도와 현재 patch load에 따라 달라질 수 있습니다.
질문: `net`이나 `net-next` 같은 주요 kernel tree에 pull request를 얼마나 자주 보냅니까? 답변: `bpf` 또는 `bpf-next`에 너무 많은 patch가 쌓이지 않도록 비교적 자주 보냅니다. 대략 각 tree에 대해 매주 말 정기적으로 보내며, patch load나 긴급성에 따라 주중에도 추가로 보낼 수 있습니다.
질문: merge window가 열려 있을 때 `bpf-next`에 patch를 적용합니까? 답변: merge window 동안에는 `bpf-next`를 처리하지 않습니다. `net-next` patch 처리와 대체로 같으므로 자세한 내용은 `Documentation/process/maintainer-netdev.rst`를 참조하십시오.
약 2주인 merge window 동안에는 `bpf-next`가 다시 열린 뒤 patch series를 재전송해 달라고 요청할 수 있습니다. Linus가 merge window 뒤 `v*-rc1`을 release하면 `bpf-next` 처리를 계속합니다.
kernel mailing list 비구독자를 위해 David S. Miller가 운영하는 `net-next` status page `http://vger.kernel.org/~davem/net-next.html`도 안내를 제공합니다.
Verifier 변경과 test case
248-265질문: BPF verifier를 변경했다면 BPF kernel selftests에 test case를 추가해야 합니까? 답변: patch가 verifier behavior를 바꾼다면 반드시 추가해야 합니다. 필요한데 빠졌다고 판단하면 변경을 accept하기 전에 test 추가를 요청할 수 있습니다.
특히 `test_verifier.c`는 LLVM BPF back end가 제한된 C code에서 생성할 수 있는 많은 corner case를 포함해 수많은 BPF test case를 추적합니다. 미래 변경이 기존 use case에 뜻하지 않은 영향을 주지 않게 하려면 test case 추가가 매우 중요합니다.
따라서 `test_verifier.c`가 추적하지 않는 verifier behavior는 잠재적으로 변경될 수 있다고 간주하십시오.
samples/bpf와 selftests 선택
266-286질문: 언제 `samples/bpf/`에 code를 추가하고 언제 BPF kernel selftests에 추가해야 합니까? 답변: 일반적으로 `samples/bpf/`보다 BPF kernel selftests 추가를 선호합니다. kernel selftest는 여러 bot이 정기 실행해 kernel regression을 검사하기 때문입니다.
BPF selftest에 test case가 많을수록 coverage가 좋아지고 우연히 깨질 가능성이 낮아집니다. BPF kernel selftest도 특정 feature의 사용법을 시연할 수 있습니다.
다만 `samples/bpf/`는 처음 시작하는 사람에게 좋은 곳이므로 간단한 feature demo는 그곳에 둘 수 있습니다. 고급 functional test와 corner-case test는 kernel selftest에 두는 편이 좋습니다.
sample이 test case처럼 보인다면 BPF kernel selftest를 선택하십시오.
bpftool과 iproute2 BPF loader
287-332질문: 언제 bpftool에 code를 추가해야 합니까? 답변: `tools/bpf/bpftool/`의 bpftool은 kernel에서 활성 상태인 BPF program과 map을 debug하고 introspection하는 중앙 userspace tool입니다. BPF 관련 UAPI 변경으로 program이나 map의 추가 정보를 dump할 수 있게 된다면 bpftool도 이를 dump하도록 확장해야 합니다.
질문: 언제 iproute2 BPF loader에 code를 추가해야 합니까? 답변: XDP나 tc layer, 예를 들어 `cls_bpf`와 관련된 UAPI 변경은 관례상 userspace 쪽 iproute2 BPF loader의 control path에도 추가합니다. 이는 UAPI를 실제 사용 가능하게 올바르게 설계하는 데 유용할 뿐 아니라 주요 downstream distribution의 더 넓은 user base에 변경을 제공하는 방법이기도 합니다.
질문: iproute2 BPF loader patch도 받습니까? 답변: 해당 patch는 `netdev@vger.kernel.org`로 보내야 합니다. BPF kernel maintainer가 직접 처리하지는 않지만 review할 수 있도록 이들도 Cc에 남겨 두십시오.
Stephen Hemminger가 운영하는 공식 iproute2 git repository는 `https://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git/`입니다.
patch subject prefix는 `[PATCH iproute2 master]` 또는 `[PATCH iproute2 net-next]`여야 합니다. `master`와 `net-next`는 patch를 적용할 target branch를 뜻합니다. kernel 변경이 `net-next` kernel tree에 들어갔다면 관련 iproute2 변경도 iproute2 `net-next` branch로 보내고, 그렇지 않으면 `master`를 대상으로 할 수 있습니다. 현재 iproute2 version이 `master`에서 release된 뒤 iproute2 `net-next` branch가 `master`로 merge됩니다.
BPF와 마찬가지로 patch는 netdev project의 patchwork에 들어가고 `shemminger`에게 delegate됩니다. queue는 `http://patchwork.ozlabs.org/project/netdev/list/?delegate=389`에서 확인할 수 있습니다.
Patch 제출 전 최소 요건
333-360질문: BPF patch를 제출하기 위한 최소 요건은 무엇입니까? 답변: 제출 전에 충분한 시간을 들여 patch를 올바르게 test하십시오. 서두르지 마십시오. maintainer가 제대로 test하지 않았음을 발견하면 좋지 않은 인상을 주며, 제출 patch의 test는 필수 요건입니다.
`bpf` tree로 가는 fix에는 반드시 `Fixes:` tag가 있어야 합니다. 영향받은 commit이 `net-next` 또는 경우에 따라 `bpf-next`에 있을 때 `bpf-next`를 대상으로 하는 fix에도 같은 규칙이 적용됩니다. `Fixes:` tag는 follow-up commit을 식별하고 backport 작업을 크게 도우므로 필수입니다.
빈 commit message가 있는 patch도 accept하지 않습니다. 시간을 들여 고품질 commit message를 작성해야 합니다.
한 달 뒤 code를 보는 다른 developer가 특정 변경을 왜 그런 방식으로 했는지, 원 author의 분석이나 가정에 결함이 있었는지 이해할 수 있어야 합니다. 따라서 적절한 근거와 변경의 use case를 설명해야 합니다.
patch가 두 개 이상인 제출에는 series의 high-level description을 담은 cover letter가 반드시 있어야 합니다. 이 summary는 BPF maintainer가 merge commit에 넣으므로 이후에도 git log에서 참조할 수 있습니다.
BPF JIT·LLVM과 BPF_INTERNAL
361-392질문: BPF JIT 또는 LLVM integration이 필요한 새 instruction이나 feature를 추가할 때 무엇을 고려해야 합니까? 답변: in-kernel BPF JIT가 활성화된 환경에서 program이 덜 효율적인 interpreter로 넘어가지 않고 architecture가 달라도 같은 user experience를 보장할 수 있도록 모든 BPF JIT를 최신 상태로 유지하려 노력합니다.
특정 architecture에 필요한 JIT 변경을 구현하거나 test할 수 없다면 관련 BPF JIT developer와 협력해 제때 feature를 구현하십시오. 도움을 줄 사람은 git log의 `arch/*/net/`에서 찾을 수 있습니다.
새 instruction에는 `test_bpf.c`, `test_verifier.c` 같은 BPF test case를 항상 추가해 넓은 coverage를 확보하고 여러 BPF JIT를 runtime에 test할 수 있게 하십시오.
새 BPF instruction 변경이 Linux kernel에 accept된 뒤에는 LLVM BPF back end에도 support를 구현하십시오. 자세한 내용은 아래 LLVM section을 참조하십시오.
질문: `BPF_INTERNAL` symbol namespace는 무엇을 위한 것입니까? 답변: `BPF_INTERNAL`로 export한 symbol은 light skeleton을 사용하는 preload kernel module 같은 BPF infrastructure만 사용할 수 있습니다. `BPF_INTERNAL` 밖의 symbol 대부분도 BPF 외부 code가 사용할 것으로 기대하지 않습니다. namespace보다 오래된 symbol이거나 누락 때문에 designation이 없을 수 있습니다.
Stable kernel에 특정 fix 요청
393-420질문: stable kernel에 특정 BPF commit이 필요하면 어떻게 합니까? 답변: 먼저 관련 `linux-*.y` branch에 그 commit이 이미 적용됐는지 `https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/`에서 확인하십시오.
적용되지 않았다면 `netdev@vger.kernel.org` kernel mailing list를 Cc에 넣고 BPF maintainer에게 mail을 보내 fix를 queue해 달라고 요청하십시오.
일반 절차는 netdev 자체와 같으며 networking subsystem 문서 `Documentation/process/maintainer-netdev.rst`도 참조하십시오.
질문: 현재 stable로 유지보수되지 않는 kernel에도 backport합니까? 답변: 하지 않습니다. stable maintainer가 현재 유지하지 않는 kernel에 특정 BPF commit이 필요하면 직접 처리해야 합니다.
현재 stable 및 longterm stable kernel 목록은 `https://www.kernel.org/`에 있습니다.
Stable 제출과 queue
421-449질문: 제출하려는 BPF patch가 stable에도 들어가야 하면 어떻게 합니까? 답변: 일반 netdev patch 제출과 같은 규칙이 적용되므로 `Documentation/process/maintainer-netdev.rst`를 참조하십시오.
patch description에 `Cc: stable@vger.kernel.org`를 절대 추가하지 말고 BPF maintainer에게 patch를 queue해 달라고 요청하십시오. git log에는 들어가지 않는 patch의 `---` 아래에 note를 적거나 단순히 mail로 요청할 수 있습니다.
질문: stable로 제출될 예정인 BPF patch queue는 어디에서 찾습니까? 답변: critical bug를 고친 patch가 `bpf` tree에 적용되면 `http://patchwork.ozlabs.org/bundle/bpf/stable/?state=*` 아래에서 stable 제출용으로 queue됩니다.
관련 commit이 mainline kernel tree에 들어갈 때까지 최소한 그곳에서 hold됩니다. 더 넓은 환경에 노출된 뒤 BPF maintainer가 queue된 patch를 stable maintainer에게 제출합니다.
BPF selftest 실행과 BTF 준비
450-490질문: BPF selftest를 어떻게 실행합니까? 답변: 새로 compile한 kernel로 boot한 뒤 clone한 git tree root를 현재 directory로 두고 BPF selftests suite로 이동해 build합니다.
$ cd tools/testing/selftests/bpf/
$ make
verifier test는 다음처럼 실행합니다.
$ sudo ./test_verifier
verifier test는 현재 수행하는 모든 check를 출력합니다. 전체 test가 끝나면 성공과 실패 정보를 summary로 표시합니다.
Summary: 418 PASSED, 0 FAILED
모든 BPF selftest를 실행하려면 다음 command가 필요합니다.
$ sudo make run_tests
자세한 내용은 kernel selftest 문서 `</dev-tools/kselftest>`를 참조하십시오. 통과하는 test 수를 최대화하려면 test 대상 kernel의 `.config`를 `tools/testing/selftests/bpf`에 있는 config file fragment와 최대한 가깝게 맞춰야 합니다.
`Documentation/bpf/btf.rst`에서 다루는 최신 BPF Type Format feature를 지원하려면 `CONFIG_DEBUG_INFO_BTF=y`로 build하는 kernel에 pahole version 1.16이 필요합니다. pahole은 dwarves package로 제공되며 `https://github.com/acmel/dwarves` source에서 build할 수도 있습니다.
pahole source와 selftest version
491-518pahole은 commit `21507cd3e97b`("pahole: add libbpf as submodule under lib/bpf") 이후 v1.13부터 libbpf definition과 API를 사용합니다. git repository에서는 `git submodule update --init --recursive`가 libbpf submodule을 갱신하므로 잘 동작합니다.
하지만 기본 GitHub release source code에는 libbpf submodule source가 없어 build 문제가 생깁니다. `https://git.kernel.org/pub/scm/devel/pahole/pahole.git/`의 tarball도 GitHub와 같습니다. 해당 libbpf submodule code를 포함한 source tarball은 `https://fedorapeople.org/~acme/dwarves`에서 받을 수 있습니다.
Fedora와 Gentoo 등 일부 distribution은 이미 pahole version 1.16 package를 제공합니다.
질문: kernel을 어느 BPF kernel selftest version으로 test해야 합니까? 답변: kernel `xyz`를 실행한다면 항상 같은 kernel `xyz`의 BPF kernel selftest를 실행하십시오. 최신 mainline tree의 BPF selftest가 언제나 통과할 것이라고 기대하면 안 됩니다.
특히 `test_bpf.c`와 `test_verifier.c`에는 많은 test case가 있으며 새 BPF test sequence가 계속 추가됩니다. verifier가 더 똑똑해져 특정 항목을 더 잘 추적하는 등의 변경에 맞춰 기존 sequence도 계속 수정됩니다.
LLVM BPF back end 확인
519-554질문: BPF를 지원하는 LLVM은 어디에서 찾습니까? 답변: LLVM의 BPF back end는 version 3.7.1부터 upstream에 포함됐습니다.
현재 모든 주요 distribution이 BPF back end를 활성화한 LLVM을 제공하므로 대부분의 use case에서는 LLVM을 직접 compile할 필요 없이 distribution package를 설치하면 됩니다.
LLVM static compiler가 지원하는 target은 `llc --version`으로 나열할 수 있습니다. 출력에 BPF target이 있는지 확인하십시오. 예시는 다음과 같습니다.
$ llc --version
LLVM (http://llvm.org/):
LLVM version 10.0.0
Optimized build.
Default target: x86_64-unknown-linux-gnu
Host CPU: skylake
Registered Targets:
aarch64 - AArch64 (little endian)
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
LLVM BPF back end에 추가된 최신 feature를 활용하려는 developer는 최신 LLVM release를 사용하는 편이 좋습니다. BPF instruction set 추가 같은 새 BPF kernel feature는 흔히 LLVM support와 함께 개발됩니다.
모든 LLVM release는 `http://releases.llvm.org/`에서 찾을 수 있습니다.
LLVM 직접 build
555-580질문: 그래도 LLVM을 직접 build하려면 어떻게 합니까? 답변: 가장 빠른 incremental build를 원하는 developer에게 Ninja build system을 권장합니다. system package manager에서 보통 `ninja` 또는 `ninja-build` package로 찾을 수 있습니다.
LLVM build prerequisite로 ninja, cmake, gcc-c++가 필요합니다. 준비한 뒤 git repository의 최신 LLVM과 clang을 다음처럼 build합니다.
$ git clone https://github.com/llvm/llvm-project.git
$ mkdir -p llvm-project/llvm/build
$ cd llvm-project/llvm/build
$ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86" \
-DLLVM_ENABLE_PROJECTS="clang" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_BUILD_RUNTIME=OFF
$ ninja
build된 binary는 `build/bin/` directory에 있으며 이 directory를 `PATH` variable로 지정할 수 있습니다.
`-DLLVM_TARGETS_TO_BUILD`는 build하려는 target과 같게 설정하십시오. 전체 target 목록은 `llvm-project/llvm/lib/Target` directory에서 찾을 수 있습니다.
LLVM BPF 문제 report
581-607질문: LLVM BPF code generation back end 문제나 LLVM이 생성했지만 verifier가 거부하는 code 문제를 BPF kernel maintainer에게 알려야 합니까? 답변: 반드시 알려야 합니다.
LLVM BPF back end는 전체 BPF infrastructure의 핵심이며 kernel 쪽 program verification과 깊이 연결됩니다. 어느 쪽에서든 발생한 문제는 조사하고 필요하면 수정해야 합니다.
따라서 netdev kernel mailing list에 문제를 제기하고 LLVM 및 kernel 부분의 BPF maintainer를 Cc에 포함하십시오.
- Yonghong Song <yhs@fb.com>
- Alexei Starovoitov <ast@kernel.org>
- Daniel Borkmann <daniel@iogearbox.net>
LLVM에는 BPF 관련 bug를 찾을 수 있는 issue tracker `https://bugs.llvm.org/buglist.cgi?quicksearch=bpf`도 있습니다. 하지만 maintainer를 Cc에 넣어 mailing list로 연락하는 편이 더 좋습니다.
새 BPF instruction의 LLVM 통합
608-644질문: kernel에 새 BPF instruction을 추가했다면 LLVM에 어떻게 통합합니까? 답변: LLVM BPF back end에는 BPF instruction set extension을 선택하는 `-mcpu` selector가 있습니다. LLVM version 20 전에는 BPF base instruction set v1인 `generic` processor target을 사용했습니다. LLVM 20부터 default processor target은 instruction set v3로 바뀌었습니다.
LLVM에는 `-mcpu=probe` option도 있습니다. host kernel이 지원하는 BPF instruction set extension을 probe해 최적 집합을 자동 선택합니다.
cross-compilation에서는 특정 version을 수동으로 선택할 수도 있습니다.
$ llc -march bpf -mcpu=help
Available CPUs for this target:
generic - Select the generic processor.
probe - Select the probe processor.
v1 - Select the v1 processor.
v2 - Select the v2 processor.
[...]
Linux kernel에 새로 추가하는 BPF instruction도 같은 scheme을 따라야 합니다. instruction set version을 올리고 extension probing을 구현해, `-mcpu=probe` user가 kernel upgrade 시 자동으로 optimization의 이점을 얻도록 하십시오.
새 BPF instruction support를 구현할 수 없다면 BPF developer에게 도움을 요청하십시오. BPF kernel selftest도 더 나은 test coverage를 위해 `-mcpu=probe`로 실행됩니다.
clang target이 생성 code에 미치는 영향
645-681질문: 어떤 경우에는 clang flag `--target=bpf`를 쓰고 다른 경우에는 underlying architecture와 일치하는 default clang target을 씁니다. 차이는 무엇이며 언제 어느 것을 사용해야 합니까? 답변: LLVM IR 생성과 optimization은 architecture independent하게 유지하려 하지만 `--target=<arch>`는 생성 code에 여전히 영향을 줍니다.
- BPF program이 file-scope inline assembly code가 있는 header file을 재귀적으로 include할 수 있습니다. default target은 이를 잘 처리하지만 BPF backend assembler는 대부분 이 assembly code를 이해하지 못하므로 `bpf` target이 실패할 수 있습니다.
- `-g` 없이 compile하면 default target의 object file에는 `.eh_frame`, `.rela.eh_frame` 같은 ELF section이 추가될 수 있지만 `bpf` target에는 생기지 않습니다.
- default target은 C switch statement를 switch table lookup과 jump operation으로 바꿀 수 있습니다. switch table은 global readonly section에 놓이므로 BPF program load가 실패합니다. `bpf` target은 switch table optimization을 지원하지 않습니다. clang option `-fno-jump-tables`로 switch table 생성을 끌 수 있습니다.
- clang `--target=bpf`에서는 underlying clang binary, default target 또는 kernel이 32-bit인지와 무관하게 pointer와 `long`/`unsigned long` type의 width가 항상 64-bit임을 보장합니다. native clang target은 underlying architecture convention을 따르므로 32-bit architecture에서는 BPF context structure의 해당 type도 32-bit가 되지만 BPF LLVM back end는 여전히 64-bit로 동작합니다. native target은 주로 CPU register width가 중요한 tracing에서 `pt_regs`나 다른 kernel structure를 순회할 때 필요합니다. 그 밖에는 일반적으로 `clang --target=bpf`를 권장합니다.
Default target과 bpf target 선택
682-704다음 경우에는 default target을 사용해야 합니다.
- program이 `ptrace.h` 같은 header file을 include하고, 그 header가 결국 file-scope host assembly code를 포함한 header를 가져옵니다.
- switch table 문제를 피하기 위해 `-fno-jump-tables`를 추가할 수 있습니다.
그 밖의 경우에는 `bpf` target을 사용할 수 있습니다. 다음 경우에는 반드시 `bpf` target을 사용해야 합니다.
- program이 BPF helper 또는 context data structure와 interface하는 pointer나 `long`/`unsigned long` type의 data structure를 사용합니다. verifier가 이 structure access를 검사하므로 native architecture가 64-bit인 BPF architecture와 일치하지 않으면 verification failure가 발생할 수 있습니다. 예를 들어 `BPF_PROG_TYPE_SK_MSG`는 `--target=bpf`를 요구합니다.
원문의 selftests link는 `https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/selftests/bpf/`를 가리킵니다.
즐거운 BPF hacking을 기원합니다.
요약과 해설
bpf_devel_QA.rst:1-704BPF 개발은 `bpf@vger.kernel.org`를 중심으로 이루어지며 patch는 fix용 `bpf`와 feature용 `bpf-next` tree를 거쳐 각각 `net`과 `net-next`, 이어 mainline으로 이동합니다. 제출 전 BPF CI와 selftest를 실행하고 target tree에 맞는 subject prefix, `Fixes:` tag, 충분한 commit message와 cover letter를 갖춰야 합니다.
stable backport는 maintainer에게 queue를 요청해야 하며 patch description에 `Cc: stable@vger.kernel.org`를 직접 넣지 않습니다. verifier나 instruction 변경에는 `test_verifier.c`, `test_bpf.c` 같은 regression test가 필수이고, 새 instruction은 각 architecture JIT와 LLVM BPF back end에도 함께 반영해야 합니다.
LLVM의 `-mcpu=probe`는 host kernel의 instruction extension을 감지합니다. clang target은 assembly header, ELF section, switch table, pointer width에 영향을 주므로 kernel structure tracing에는 native target을 고려하되 BPF helper·context와 맞닿는 64-bit data layout에는 `--target=bpf`를 사용해야 합니다.