diff mbox series

[bpf-next,v2,2/3] bpf: Document usage of the new BPF_KFUNC macro

Message ID 20230123171506.71995-3-void@manifault.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series Add BPF_KFUNC macro for kfunc definitions | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 3 maintainers not CCed: linux-doc@vger.kernel.org yhs@fb.com corbet@lwn.net
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 146 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-19 fail Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32 on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_progs_no_alu32_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_progs_no_alu32_parallel on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-29 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-30 success Logs for test_progs_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-32 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-33 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-34 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-35 success Logs for test_verifier on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-37 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-38 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-21 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-36 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-31 success Logs for test_progs_parallel on s390x with gcc
bpf/vmtest-bpf-next-PR fail PR summary
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-7 success Logs for llvm-toolchain
bpf/vmtest-bpf-next-VM_Test-8 success Logs for set-matrix

Commit Message

David Vernet Jan. 23, 2023, 5:15 p.m. UTC
Now that the BPF_KFUNC macro has been added to linux/btf.h, include a
description of how to use it in the kfuncs.rst file. Along the way, do
some cleanup of kfuncs.rst which allows the description to be more
cleanly integrated into the doc.

Signed-off-by: David Vernet <void@manifault.com>
---
 Documentation/bpf/kfuncs.rst | 93 +++++++++++++++++++-----------------
 1 file changed, 50 insertions(+), 43 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
index 9fd7fb539f85..372f65aa87f7 100644
--- a/Documentation/bpf/kfuncs.rst
+++ b/Documentation/bpf/kfuncs.rst
@@ -14,55 +14,56 @@  kernel.
 2. Defining a kfunc
 ===================
 
-There are two ways to expose a kernel function to BPF programs, either make an
-existing function in the kernel visible, or add a new wrapper for BPF. In both
-cases, care must be taken that BPF program can only call such function in a
-valid context. To enforce this, visibility of a kfunc can be per program type.
+There are two ways to expose a kernel function to BPF programs: either make an
+existing function in the kernel visible, or add a new function that is only
+invoked from BPF. In both cases, care must be taken that BPF program can only
+call the function in a valid context. To enforce this, attributes may be set on
+a kfunc which inform the verifier of how the kfunc should be invoked in order
+to ensure safety. Additionally, when kfuncs are first registered, they are
+registered for a specific program type.
+
+2.1 Using BPF_KFUNC macro
+-------------------------
+
+When defining a kfunc, always wrap its signature in the ``BPF_KFUNC`` macro.
+This macro adds the necessary attributes to prevent the compiler from
+optimizing away dead code, as some kfuncs may not be invoked anywhere in the
+kernel itself, or may e.g. be removed in LTO builds. If an additional
+annotation is required to prevent such an issue with your kfunc, it is likely a
+bug and should be added to the definition of the macro so that other kfuncs are
+similarly protected. This macro also provides an easy way to grep for kfunc
+definitions.
+
+An example is given below:
 
-If you are not creating a BPF wrapper for existing kernel function, skip ahead
-to :ref:`BPF_kfunc_nodef`.
-
-2.1 Creating a wrapper kfunc
-----------------------------
-
-When defining a wrapper kfunc, the wrapper function should have extern linkage.
-This prevents the compiler from optimizing away dead code, as this wrapper kfunc
-is not invoked anywhere in the kernel itself. It is not necessary to provide a
-prototype in a header for the wrapper kfunc.
-
-An example is given below::
-
-        /* Disables missing prototype warnings */
-        __diag_push();
-        __diag_ignore_all("-Wmissing-prototypes",
-                          "Global kfuncs as their definitions will be in BTF");
+.. code-block:: c
 
-        struct task_struct *bpf_find_get_task_by_vpid(pid_t nr)
+        BPF_KFUNC(void bpf_memzero(void *mem, int mem__sz))
         {
-                return find_get_task_by_vpid(nr);
+        ...
         }
 
-        __diag_pop();
-
-A wrapper kfunc is often needed when we need to annotate parameters of the
-kfunc. Otherwise one may directly make the kfunc visible to the BPF program by
-registering it with the BPF subsystem. See :ref:`BPF_kfunc_nodef`.
+It is not necessary to provide a prototype in a header for a kfunc (the macro
+also takes care of this), though you may provide one if the kfunc is invoked
+elsewhere in the main kernel.
 
 2.2 Annotating kfunc parameters
 -------------------------------
 
-Similar to BPF helpers, there is sometime need for additional context required
-by the verifier to make the usage of kernel functions safer and more useful.
-Hence, we can annotate a parameter by suffixing the name of the argument of the
-kfunc with a __tag, where tag may be one of the supported annotations.
+Similar to BPF helpers, the verifier sometimes requires additional context to
+make the usage of kernel functions safer and more useful.  Hence, we can
+annotate a parameter by suffixing the name of the argument of the kfunc with a
+__tag, where tag may be one of the following supported annotations.
 
 2.2.1 __sz Annotation
 ---------------------
 
 This annotation is used to indicate a memory and size pair in the argument list.
-An example is given below::
+An example is given below:
+
+.. code-block:: c
 
-        void bpf_memzero(void *mem, int mem__sz)
+        BPF_KFUNC(void bpf_memzero(void *mem, int mem__sz))
         {
         ...
         }
@@ -80,9 +81,11 @@  the verifier must check the scalar argument to be a known constant, which does
 not indicate a size parameter, and the value of the constant is relevant to the
 safety of the program.
 
-An example is given below::
+An example is given below:
+
+.. code-block:: c
 
-        void *bpf_obj_new(u32 local_type_id__k, ...)
+        BPF_KFUNC(void *bpf_obj_new(u32 local_type_id__k, ...))
         {
         ...
         }
@@ -96,8 +99,6 @@  Hence, whenever a constant scalar argument is accepted by a kfunc which is not a
 size parameter, and the value of the constant matters for program safety, __k
 suffix should be used.
 
-.. _BPF_kfunc_nodef:
-
 2.3 Using an existing kernel function
 -------------------------------------
 
@@ -109,17 +110,21 @@  and whether it is safe to do so.
 2.4 Annotating kfuncs
 ---------------------
 
-In addition to kfuncs' arguments, verifier may need more information about the
+In addition to kfunc arguments, verifier may need more information about the
 type of kfunc(s) being registered with the BPF subsystem. To do so, we define
-flags on a set of kfuncs as follows::
+flags on a set of kfuncs as follows:
+
+.. code-block:: c
 
         BTF_SET8_START(bpf_task_set)
         BTF_ID_FLAGS(func, bpf_get_task_pid, KF_ACQUIRE | KF_RET_NULL)
         BTF_ID_FLAGS(func, bpf_put_pid, KF_RELEASE)
+        BTF_ID_FLAGS(func, bpf_task_is_kthread) /* Flags are optional */
         BTF_SET8_END(bpf_task_set)
 
-This set encodes the BTF ID of each kfunc listed above, and encodes the flags
-along with it. Ofcourse, it is also allowed to specify no flags.
+This set encodes the BTF ID of each kfunc listed above, along with an optional
+set of flags which provide context to the verifier about how the kfunc should
+be invoked.
 
 2.4.1 KF_ACQUIRE flag
 ---------------------
@@ -205,7 +210,9 @@  into consideration.
 
 Once the kfunc is prepared for use, the final step to making it visible is
 registering it with the BPF subsystem. Registration is done per BPF program
-type. An example is shown below::
+type. An example is shown below:
+
+.. code-block:: c
 
         BTF_SET8_START(bpf_task_set)
         BTF_ID_FLAGS(func, bpf_get_task_pid, KF_ACQUIRE | KF_RET_NULL)