diff --git a/docs/ebpf-library/libbpf/ebpf/index.md b/docs/ebpf-library/libbpf/ebpf/index.md index 87cd2f1..46c3b89 100644 --- a/docs/ebpf-library/libbpf/ebpf/index.md +++ b/docs/ebpf-library/libbpf/ebpf/index.md @@ -6,7 +6,7 @@ Libbpf contains a number of C header files containing mostly pre-processor macro The `bpf_helper_defs.h` file is automatically generated from the kernel sources. It contains forward declarations for every type that is used by [eBPF helper functions](../../../linux/helper-function/index.md) and somewhat special forward declarations for the helper functions themselves. -For example, the `bpf_map_lookup_elem` function is declared as: +For example, the [`bpf_map_lookup_elem`](../../../linux/helper-function/bpf_map_lookup_elem.md) function is declared as: `#!c static void *(* const bpf_map_lookup_elem)(void *map, const void *key) = (void *) 1;` @@ -14,7 +14,7 @@ The normal forward declaration of this function would be `#!c void *bpf_map_lookup_elem(void *map, const void *key);`. -But what the special declaration does is it casts a pointer of value `1` to a const static function pointer. This causes the compiler to emit a `call 1` instruction which the kernel recognizes as a call to the `bpf_map_lookup_elem` function. +But what the special declaration does is it casts a pointer of value `1` to a const static function pointer. This causes the compiler to emit a `call 1` instruction which the kernel recognizes as a call to the [`bpf_map_lookup_elem`](../../../linux/helper-function/bpf_map_lookup_elem.md) function. It is entirely possible to copy parts of this file if you are only interested in specific helper functions and their types and even modify their definitions to suit your needs. Though for most people it will be best to include the whole file. diff --git a/docs/linux/concepts/SUMMARY.md b/docs/linux/concepts/SUMMARY.md index 65751df..7d6e505 100644 --- a/docs/linux/concepts/SUMMARY.md +++ b/docs/linux/concepts/SUMMARY.md @@ -10,5 +10,5 @@ * [Resource Limit](resource-limit.md) * [AF_XDP](af_xdp.md) * [KFuncs](kfuncs.md) -* [dynptrs](dynptrs.md) -* [token](token.md) +* [Dynptrs](dynptrs.md) +* [Token](token.md) diff --git a/docs/linux/concepts/af_xdp.md b/docs/linux/concepts/af_xdp.md index ef2b117..e037d60 100644 --- a/docs/linux/concepts/af_xdp.md +++ b/docs/linux/concepts/af_xdp.md @@ -4,7 +4,7 @@ description: "This page explains the concept of AF_XDP in depth, AF_XDP being a --- # AF_XDP -The kernel allows process to create sockets under the Address Family Express Data Path (AF_XDP) address family. This is a special socket type which in combination with an XDP program can perform full or partial kernel bypass. Bypassing the kernel network stack can increase performance in certain use cases. A socket created under the AF_XDP address family is also referred to as a XSK (XDP Socket). +The kernel allows process to create sockets under the Address Family Express Data Path (AF_XDP) address family. This is a special socket type which in combination with an [XDP program](../program-type/BPF_PROG_TYPE_XDP.md) can perform full or partial kernel bypass. Bypassing the kernel network stack can increase performance in certain use cases. A socket created under the AF_XDP address family is also referred to as a XSK (XDP Socket). Examples of such use cases are: @@ -12,7 +12,7 @@ Examples of such use cases are: * DDoS protection - If complex processing across multiple packets is required, eBPF programs can't keep up, thus forwarding traffic to user space for analysis might be needed. * Application specific optimization - The Linux network stack by necessity needs to handle a lot of protocols and edge cases which are not applicable to workloads you are running. This means paying performance cost for features you are not using. While not easy, one can implement a custom network stack specific to their needs, to eke out every drop of performance. -All ingress traffic is first processes by an XDP program, it can make a decision on which traffic to pass to the stack and which to bypass. This is powerful since it allows a user to bypass traffic for very specific applications, ports and/or protocols without disrupting the normal packet processing. Unlike other kernel bypass techniques such as `PACKET_MMAP` or `PF_RING` which require you to handle all traffic and re-implement every protocol needed for the host to function. +All ingress traffic is first processes by an [XDP program](../program-type/BPF_PROG_TYPE_XDP.md), it can make a decision on which traffic to pass to the stack and which to bypass. This is powerful since it allows a user to bypass traffic for very specific applications, ports and/or protocols without disrupting the normal packet processing. Unlike other kernel bypass techniques such as `PACKET_MMAP` or `PF_RING` which require you to handle all traffic and re-implement every protocol needed for the host to function. ## Usage @@ -47,7 +47,7 @@ static const int umem_len = chunk_size * chunk_count; unsigned char[chunk_count][chunk_size] umem = malloc(umem_len); ``` -Now that we have a UMEM, link it to the socket via the `setsockopt` syscall: +Now that we have a UMEM, link it to the socket via the [`setsockopt`](https://man7.org/linux/man-pages/man3/setsockopt.3p.html) syscall: ```c struct xdp_umem_reg { @@ -69,13 +69,13 @@ if (!setsockopt(fd, SOL_XDP, XDP_UMEM_REG, &umem_reg, sizeof(umem_reg))) // handle error ``` -Next up are our ring buffers. These are allocated by the kernel when we tell the kernel how large we want each ring buffer to be via a `setsockopt` syscall. After allocation, we can map the ring buffer into the memory of our process via the `mmap` syscall. +Next up are our ring buffers. These are allocated by the kernel when we tell the kernel how large we want each ring buffer to be via a [`setsockopt`](https://man7.org/linux/man-pages/man3/setsockopt.3p.html) syscall. After allocation, we can map the ring buffer into the memory of our process via the [`mmap`](https://man7.org/linux/man-pages/man2/mmap.2.html) syscall. The following process should be repeated for each ring buffer (with different options, which will be pointed out): We have to determine the desired ring buffer size, which must be a power of 2 for example `128`, `256`, `512`, `1024` etc. The sizes of the ring buffers can be tweaked and can differ from ring buffer to ring buffer, we will pick `512` for this example. -We inform the kernel of our chosen size via a `setsockopt` syscall: +We inform the kernel of our chosen size via a [`setsockopt`](https://man7.org/linux/man-pages/man3/setsockopt.3p.html) syscall: ```c static const int ring_size = 512; @@ -83,7 +83,7 @@ if (!setsockopt(fd, SOL_XDP, {XDP_RX_RING,XDP_TX_RING,XDP_UMEM_FILL_RING,XDP_UME // handle error ``` -After we have set the sizes for all ring buffers we can request the `mmap` offsets with a `getsockopt` syscall: +After we have set the sizes for all ring buffers we can request the [`mmap`](https://man7.org/linux/man-pages/man2/mmap.2.html) offsets with a [`getsockopt`](https://man7.org/linux/man-pages/man3/getsockopt.3p.html) syscall: ```c struct xdp_ring_offset { @@ -308,7 +308,7 @@ The process of transferring data between the NIC and UMEM can work in copy or ze You can request an explicit mode by specifying the `XDP_COPY` or `XDP_ZEROCOPY` flags when performing the bind syscall. If zero-copy mode is requested but not available, the bind syscall will result in an error. -Additionally, a bound socket can be queried with `getsockopt` and the `XDP_OPTIONS` option and `struct xdp_options` value. If the flag `XDP_OPTIONS_ZEROCOPY` is set, then the socket operates in zero-copy mode. +Additionally, a bound socket can be queried with [`getsockopt`](https://man7.org/linux/man-pages/man3/getsockopt.3p.html) and the `XDP_OPTIONS` option and `struct xdp_options` value. If the flag `XDP_OPTIONS_ZEROCOPY` is set, then the socket operates in zero-copy mode. #### Headroom diff --git a/docs/linux/concepts/functions.md b/docs/linux/concepts/functions.md index 31a474e..e3a8e38 100644 --- a/docs/linux/concepts/functions.md +++ b/docs/linux/concepts/functions.md @@ -16,7 +16,7 @@ In [:octicons-tag-24: v4.16](https://github.com/torvalds/linux/commit/cc8b0b92a1 ### Function inlining -By default, the compiler will chose inline a function or to keep it a separate function. Compilers can be encouraged to inline or not inline a function with arguments like `__attribute__((always_inline))` or `__attribute__((noinline))`. Inlined functions do not incur the overhead of a function call as they will become part of the calling function. Inlined functions can also be optimized per call site since arguments are known. +By default, the compiler will chose inline a function or to keep it a separate function. Compilers can be encouraged to inline or not inline a function with arguments like `__attribute__((always_inline))`/[`__always_inline`](../../ebpf-library/libbpf/ebpf/__always_inline.md) or `__attribute__((noinline))`/[`__noinline`](../../ebpf-library/libbpf/ebpf/__noinline.md). Inlined functions do not incur the overhead of a function call as they will become part of the calling function. Inlined functions can also be optimized per call site since arguments are known. ### Tail calls @@ -42,8 +42,8 @@ In [:octicons-tag-24: v5.13](https://github.com/torvalds/linux/commit/69c087ba62 In [:octicons-tag-24: v6.8](https://github.com/torvalds/linux/commit/94e1c70a34523b5e1529e4ec508316acc6a26a2b) global function argument annotation were added. These are a set of annotations (in practice these are BTF decl tags), which if added to an attribute, tell the verifier to restrict the input values to the function. Possible tags are: -* `__arg_ctx` - The argument is a pointer to a program context. -* `__arg_nonnull` - The argument can not be NULL. -* `__arg_nullable` - The argument can be NULL. -* `__arg_trusted` - The argument must be a [trusted value](kfuncs.md#kf_trusted_args). -* `__arg_arena` - The argument must be a pointer to a [memory arena](../map-type/BPF_MAP_TYPE_ARENA.md). +* [`__arg_ctx`](../../ebpf-library/libbpf/ebpf/__arg_ctx.md) - The argument is a pointer to a program context. +* [`__arg_nonnull`](../../ebpf-library/libbpf/ebpf/__arg_nonnull.md) - The argument can not be NULL. +* [`__arg_nullable`](../../ebpf-library/libbpf/ebpf/__arg_nullable.md) - The argument can be NULL. +* [`__arg_trusted`](../../ebpf-library/libbpf/ebpf/__arg_trusted.md) - The argument must be a [trusted value](kfuncs.md#kf_trusted_args). +* [`__arg_arena`](../../ebpf-library/libbpf/ebpf/__arg_arena.md) - The argument must be a pointer to a [memory arena](../map-type/BPF_MAP_TYPE_ARENA.md). diff --git a/docs/linux/concepts/kfuncs.md b/docs/linux/concepts/kfuncs.md index cc3de8d..f34c5a8 100644 --- a/docs/linux/concepts/kfuncs.md +++ b/docs/linux/concepts/kfuncs.md @@ -45,7 +45,7 @@ char _license[] SEC("license") = "GPL"; ``` !!! note - The definition of `__ksym` is `#define __ksym __attribute__((section(".ksyms")))` + The definition of [`__ksym`](../../ebpf-library/libbpf/ebpf/__ksym.md) is `#define __ksym __attribute__((section(".ksyms")))` ### Kernel modules diff --git a/docs/linux/concepts/loops.md b/docs/linux/concepts/loops.md index 2f4a4ae..8873a57 100644 --- a/docs/linux/concepts/loops.md +++ b/docs/linux/concepts/loops.md @@ -73,7 +73,7 @@ In [:octicons-tag-24: v6.4](https://github.com/torvalds/linux/commit/06accc8779c The advantage of this method is that the verifier only has to check two states as opposed to the amount of iterations like with a bounded loop and we don't require a callback function like with the loop helper. -Every iterator type has a `bpf_iter__new` function to initialize the iterator, a `bpf_iter__next` function to get the next element, and a `bpf_iter__destroy` function to clean up the iterator. In the case of the numeric iterator, the `bpf_iter_num_new`, `bpf_iter_num_next` and `bpf_iter_num_destroy` functions are used. +Every iterator type has a `bpf_iter__new` function to initialize the iterator, a `bpf_iter__next` function to get the next element, and a `bpf_iter__destroy` function to clean up the iterator. In the case of the numeric iterator, the [`bpf_iter_num_new`](../kfuncs/bpf_iter_num_new.md), [`bpf_iter_num_next`](../kfuncs/bpf_iter_num_next.md) and [`bpf_iter_num_destroy`](../kfuncs/bpf_iter_bits_destroy.md) functions are used. The most basic example of a numeric iterator is: diff --git a/docs/linux/concepts/maps.md b/docs/linux/concepts/maps.md index bcea590..1b9d849 100644 --- a/docs/linux/concepts/maps.md +++ b/docs/linux/concepts/maps.md @@ -47,36 +47,36 @@ struct { ``` -The `__uint` and `__type` macros used in the above example are typically used to make the type definition easier to read. -They are defined in [`tools/lib/bpf/bpf_helpers.h`](https://elixir.bootlin.com/linux/v6.2.2/source/tools/lib/bpf/bpf_helpers.h). +The [`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md), [`__type`](../../ebpf-library/libbpf/ebpf/__type.md), [`__array`](../../ebpf-library/libbpf/ebpf/__array.md) and [`__ulong`](../../ebpf-library/libbpf/ebpf/__ulong.md) macros used in the above example are typically used to make the type definition easier to read. ```c #define __uint(name, val) int (*name)[val] #define __type(name, val) typeof(val) *name #define __array(name, val) typeof(val) *name[] +#define __ulong(name, val) enum { ___bpf_concat(__unique_value, __COUNTER__) = val } name ``` The `name` part of these macros refers to field names of the to be created structure. Not all names are recognized by libbpf and compatible libraries. However, the following are: -* `type` (`__uint`) - enum, see the [map types](../map-type/index.md) index for all valid options. -* `max_entries` (`__uint`) - int indicating the maximum amount of entries. -* `map_flags` (`__uint`) - a bitfield of flags, see [flags section](../syscall/BPF_MAP_CREATE.md#flags) in map load syscall command for valid options. -* `numa_node` (`__uint`) - the ID of the NUMA node on which to place the map. -* `key_size` (`__uint`) - the size of the key in bytes. This field is mutually exclusive with the `key` field. -* `key` (`__type`) - the type of the key. This field is mutually exclusive with the `key_size` field. -* `value_size` (`__uint`) - the size of the value in bytes. This field is mutually exclusive with the `value` and `values` fields. -* `value` (`__type`) - the type of the value. This field is mutually exclusive with the `value` and `value_size` fields. -* `values` (`__array`) - see [static values section](#static-values). This field is mutually exclusive with the `value` and `value_size` field. -* `pinning` (`__uint`) - `LIBBPF_PIN_BY_NAME` or `LIBBPF_PIN_NONE` see [pinning page](pinning.md) for details. -* `map_extra` (`__uint`) - Addition settings, currently only used by bloom filters which use the lowest 4 bits to indicate the amount of hashes used in the bloom filter. +* `type` ([`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md)) - enum, see the [map types](../map-type/index.md) index for all valid options. +* `max_entries` ([`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md)) - int indicating the maximum amount of entries. +* `map_flags` ([`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md)) - a bitfield of flags, see [flags section](../syscall/BPF_MAP_CREATE.md#flags) in map load syscall command for valid options. +* `numa_node` ([`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md)) - the ID of the NUMA node on which to place the map. +* `key_size` ([`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md)) - the size of the key in bytes. This field is mutually exclusive with the `key` field. +* `key` ([`__type`](../../ebpf-library/libbpf/ebpf/__type.md)) - the type of the key. This field is mutually exclusive with the `key_size` field. +* `value_size` ([`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md)) - the size of the value in bytes. This field is mutually exclusive with the `value` and `values` fields. +* `value` ([`__type`](../../ebpf-library/libbpf/ebpf/__type.md))) - the type of the value. This field is mutually exclusive with the `value` and `value_size` fields. +* `values` ([`__array`](../../ebpf-library/libbpf/ebpf/__array.md)) - see [static values section](#static-values). This field is mutually exclusive with the `value` and `value_size` field. +* `pinning` ([`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md)) - `LIBBPF_PIN_BY_NAME` or `LIBBPF_PIN_NONE` see [pinning page](pinning.md) for details. +* `map_extra` ([`__uint`](../../ebpf-library/libbpf/ebpf/__uint.md)) - Addition settings, currently only used by bloom filters which use the lowest 4 bits to indicate the amount of hashes used in the bloom filter. Typically, only the `type`, `key`/`key_size`, `value`/`values`/`value_size`, and `max_entries` fields are required. #### Static values -The `values` map field has a syntax when used, it is the only field to use the `__array` macro and requires us to initialize our map constant with a value. Its purpose is to populate the contents of the map during loading without having to do so manually via a userspace application. This is especially handy for users who use `ip`, `tc`, or `bpftool` to load their programs. +The `values` map field has a syntax when used, it is the only field to use the [`__array`](../../ebpf-library/libbpf/ebpf/__array.md) macro and requires us to initialize our map constant with a value. Its purpose is to populate the contents of the map during loading without having to do so manually via a userspace application. This is especially handy for users who use `ip`, `tc`, or `bpftool` to load their programs. -The `val` part of the `__array` parameter should contain a type describing the individual array elements. The values we would like to pre-populate should go into the value part of the struct initialization. +The `val` part of the [`__array`](../../ebpf-library/libbpf/ebpf/__array.md) parameter should contain a type describing the individual array elements. The values we would like to pre-populate should go into the value part of the struct initialization. The following examples show how to pre-populate a map-in-map: diff --git a/docs/linux/concepts/resource-limit.md b/docs/linux/concepts/resource-limit.md index 9045bc2..3392c1c 100644 --- a/docs/linux/concepts/resource-limit.md +++ b/docs/linux/concepts/resource-limit.md @@ -8,7 +8,7 @@ The Linux kernel has protection mechanisms that prevent processes from taking up ## Rlimit -rlimit or "resource limit" is a system to track and limit the amount of certain resources you are allowed to use. One of the things it limits is the amount of "locked memory" https://man7.org/linux/man-pages/man2/getrlimit.2.html +rlimit or "resource limit" is a system to track and limit the amount of certain resources you are allowed to use. One of the things it limits is the amount of "locked memory" [https://man7.org/linux/man-pages/man2/getrlimit.2.html](https://man7.org/linux/man-pages/man2/getrlimit.2.html) Until kernel version v5.11 this mechanism was used to track and limit the memory usage of BPF maps which count towards the locked memory limit, so you commonly would have to increase or disable this rlimit which requires an additional capability `CAP_SYS_RESOURCE`. diff --git a/docs/linux/concepts/verifier.md b/docs/linux/concepts/verifier.md index d3b1253..a76b9a8 100644 --- a/docs/linux/concepts/verifier.md +++ b/docs/linux/concepts/verifier.md @@ -87,4 +87,4 @@ Additionally, global functions can be replaced by [`freplace`](../program-type/B The [`bpf_for_each_map_elem`](../helper-function/bpf_for_each_map_elem.md) helper also introduced the concept of callbacks. This allows users to declare a static function that is not directly called by the BPF program but is passed as function pointer to a helper to be called. -In later versions this mechanism is also used for [timers](timers.md), `bpf_find_vma`, and [loops](loops.md). +In later versions this mechanism is also used for [timers](timers.md), [`bpf_find_vma`](../helper-function/bpf_find_vma.md), and [loops](loops.md). diff --git a/docs/linux/helper-function/index.md b/docs/linux/helper-function/index.md index cd47eda..7812154 100644 --- a/docs/linux/helper-function/index.md +++ b/docs/linux/helper-function/index.md @@ -71,7 +71,7 @@ These helpers are used with [`BPF_MAP_TYPE_QUEUE`](../map-type/BPF_MAP_TYPE_QUEU ### Ring buffer helper -These helpers are used with `BPF_MAP_TYPE_RINGBUF` maps. +These helpers are used with [`BPF_MAP_TYPE_RINGBUF`](../map-type/BPF_MAP_TYPE_RINGBUF.md) maps. * [`bpf_ringbuf_output`](bpf_ringbuf_output.md) * [`bpf_ringbuf_reserve`](bpf_ringbuf_reserve.md) @@ -96,41 +96,41 @@ These helpers are used with [`BPF_MAP_TYPE_SOCKHASH`](../map-type/BPF_MAP_TYPE_S ### Task storage helpers -These helpers are used with `BPF_MAP_TYPE_TASK_STORAGE` maps. +These helpers are used with [`BPF_MAP_TYPE_TASK_STORAGE`](../map-type/BPF_MAP_TYPE_TASK_STORAGE.md) maps. * [`bpf_task_storage_get`](bpf_task_storage_get.md) * [`bpf_task_storage_delete`](bpf_task_storage_delete.md) ### Inode storage helpers -These helpers are used with `BPF_MAP_TYPE_INODE_STORAGE` maps. +These helpers are used with [`BPF_MAP_TYPE_INODE_STORAGE`](../map-type/BPF_MAP_TYPE_INODE_STORAGE.md) maps. * [`bpf_inode_storage_get`](bpf_inode_storage_get.md) * [`bpf_inode_storage_delete`](bpf_inode_storage_delete.md) ### Socket storage helpers -These helpers are used with `BPF_MAP_TYPE_SK_STORAGE` maps. +These helpers are used with [`BPF_MAP_TYPE_SK_STORAGE`](../map-type/BPF_MAP_TYPE_SK_STORAGE.md) maps. * [`bpf_sk_storage_get`](bpf_sk_storage_get.md) * [`bpf_sk_storage_delete`](bpf_sk_storage_delete.md) ### Local cGroup storage helpers -These helpers are used with `BPF_MAP_TYPE_CGROUP_STORAGE` and `BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE` maps. +These helpers are used with [`BPF_MAP_TYPE_CGROUP_STORAGE`](../map-type/BPF_MAP_TYPE_CGROUP_STORAGE.md) and [`BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE`](../map-type/BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE.md) maps. * [`bpf_get_local_storage`](bpf_get_local_storage.md) ### Global cGroup storage helpers -These helpers are used with `BPF_MAP_TYPE_CGRP_STORAGE` maps. +These helpers are used with [`BPF_MAP_TYPE_CGRP_STORAGE`](../map-type/BPF_MAP_TYPE_CGRP_STORAGE.md) maps. * [`bpf_cgrp_storage_get`](bpf_cgrp_storage_get.md) * [`bpf_cgrp_storage_delete`](bpf_cgrp_storage_delete.md) ### User ring buffer -These helpers are related to `BPF_MAP_TYPE_USER_RINGBUF` maps. +These helpers are related to [`BPF_MAP_TYPE_USER_RINGBUF`](../map-type/BPF_MAP_TYPE_USER_RINGBUF.md) maps. * [`bpf_user_ringbuf_drain`](bpf_user_ringbuf_drain.md) @@ -169,7 +169,7 @@ These helpers are used to influence processes. ### Tracing helpers -These helpers return information specific to `BPF_PROG_TYPE_TRACING` programs. +These helpers return information specific to [`BPF_PROG_TYPE_TRACING`](../program-type/BPF_PROG_TYPE_TRACING.md) programs. * [`bpf_get_func_ip`](bpf_get_func_ip.md) * [`bpf_get_func_arg`](bpf_get_func_arg.md) @@ -179,7 +179,7 @@ These helpers return information specific to `BPF_PROG_TYPE_TRACING` programs. ### Perf event helpers -These helpers return information specific to `BPF_PROG_TYPE_PERF_EVENT` programs. +These helpers return information specific to [`BPF_PROG_TYPE_PERF_EVENT`](../program-type/BPF_PROG_TYPE_PERF_EVENT.md) programs. * [`bpf_perf_prog_read_value`](bpf_perf_prog_read_value.md) @@ -310,7 +310,7 @@ These helpers redirect the flow of packets in some way. ### XDP helpers -These helpers are specific to `BPF_PROG_TYPE_XDP` programs. +These helpers are specific to [`BPF_PROG_TYPE_XDP`](../program-type/BPF_PROG_TYPE_XDP.md) programs. * [`bpf_xdp_adjust_head`](bpf_xdp_adjust_head.md) * [`bpf_xdp_adjust_tail`](bpf_xdp_adjust_tail.md) @@ -321,7 +321,7 @@ These helpers are specific to `BPF_PROG_TYPE_XDP` programs. ### Socket message helpers -These helpers are specific to `BPF_PROG_TYPE_SK_MSG` programs. +These helpers are specific to [`BPF_PROG_TYPE_SK_MSG`](../program-type/BPF_PROG_TYPE_SK_MSG.md) programs. * [`bpf_msg_apply_bytes`](bpf_msg_apply_bytes.md) * [`bpf_msg_cork_bytes`](bpf_msg_cork_bytes.md) @@ -331,7 +331,7 @@ These helpers are specific to `BPF_PROG_TYPE_SK_MSG` programs. ### LWT helpers -These helpers are specific to `BPF_PROG_TYPE_LWT_*` programs. +These helpers are specific to [`BPF_PROG_TYPE_LWT_*`](../program-type/index.md#light-weight-tunnel-program-types) programs. * [`bpf_lwt_push_encap`](bpf_lwt_push_encap.md) * [`bpf_lwt_seg6_store_bytes`](bpf_lwt_seg6_store_bytes.md) @@ -379,7 +379,7 @@ These helpers are related to socket. ### Socket ops helpers -These helpers are specific to `BPF_PROG_TYPE_SOCK_OPS` programs. +These helpers are specific to [`BPF_PROG_TYPE_SOCK_OPS`](../program-type/BPF_PROG_TYPE_SOCK_OPS.md) programs. * [`bpf_load_hdr_opt`](bpf_load_hdr_opt.md) * [`bpf_store_hdr_opt`](bpf_store_hdr_opt.md) @@ -387,7 +387,7 @@ These helpers are specific to `BPF_PROG_TYPE_SOCK_OPS` programs. ## Infrared related helpers -These helpers are specific to `BPF_PROG_TYPE_LIRC_MODE2` programs. +These helpers are specific to [`BPF_PROG_TYPE_LIRC_MODE2`](../program-type/BPF_PROG_TYPE_LIRC_MODE2.md) programs. * [`bpf_rc_repeat`](bpf_rc_repeat.md) * [`bpf_rc_keydown`](bpf_rc_keydown.md) @@ -395,7 +395,7 @@ These helpers are specific to `BPF_PROG_TYPE_LIRC_MODE2` programs. ## Syscall helpers -These helpers are specific to `BPF_PROG_TYPE_SYSCALL` programs. +These helpers are specific to [`BPF_PROG_TYPE_SYSCALL`](../program-type/BPF_PROG_TYPE_SYSCALL.md) programs. * [`bpf_sys_bpf`](bpf_sys_bpf.md) * [`bpf_btf_find_by_name_kind`](bpf_btf_find_by_name_kind.md) @@ -404,7 +404,7 @@ These helpers are specific to `BPF_PROG_TYPE_SYSCALL` programs. ## LSM helpers -These helpers are specific to `BPF_PROG_TYPE_LSM` programs. +These helpers are specific to [`BPF_PROG_TYPE_LSM`](../program-type/BPF_PROG_TYPE_LSM.md) programs. * [`bpf_bprm_opts_set`](bpf_bprm_opts_set.md) * [`bpf_ima_inode_hash`](bpf_ima_inode_hash.md) @@ -412,7 +412,7 @@ These helpers are specific to `BPF_PROG_TYPE_LSM` programs. ## Sysctl helpers -These helpers are specific to `BPF_PROG_TYPE_CGROUP_SYSCTL` programs. +These helpers are specific to [`BPF_PROG_TYPE_CGROUP_SYSCTL`](../program-type/BPF_PROG_TYPE_CGROUP_SYSCTL.md) programs. * [`bpf_sysctl_get_name`](bpf_sysctl_get_name.md) * [`bpf_sysctl_get_current_value`](bpf_sysctl_get_current_value.md) diff --git a/docs/linux/kfuncs/index.md b/docs/linux/kfuncs/index.md index b5795b9..1080ef8 100644 --- a/docs/linux/kfuncs/index.md +++ b/docs/linux/kfuncs/index.md @@ -11,7 +11,7 @@ hide: toc Helper functions enjoy the stability guarantee offered by the user API, as explained in [documentation about stability guarantees of the helper functions](../helper-function/index.md#stability-guarantees). But KFuncs do not enjoy those same guarantees. -Although KFuncs are not expected to be very volatile, still defensive programming techniques are advised. +Although KFuncs are not expected to be very volatile, defensive programming techniques are still advised. Otherwise helper functions should be preferred over KFuncs. ## cGroup resource statistic KFuncs diff --git a/docs/linux/map-type/index.md b/docs/linux/map-type/index.md index 325e21e..b0bfc96 100644 --- a/docs/linux/map-type/index.md +++ b/docs/linux/map-type/index.md @@ -86,12 +86,12 @@ This map type replaces a structure containing function pointers in the kernel an ## Per CPU maps -There are a number of per-CPU map types like `BPF_MAP_TYPE_PERCPU_HASH` and `BPF_MAP_TYPE_PERCPU_ARRAY`. These are per-CPU variants of their base map types. Like the name implies these maps consists of multiple copies, one for each logical CPU on the host. Programs running in the context of CPU#0 for example will see different map contents as a program running on CPU#2. +There are a number of per-CPU map types like [`BPF_MAP_TYPE_PERCPU_HASH`](BPF_MAP_TYPE_PERCPU_HASH.md) and [`BPF_MAP_TYPE_PERCPU_ARRAY`](BPF_MAP_TYPE_PERCPU_ARRAY.md). These are per-CPU variants of their base map types. Like the name implies these maps consists of multiple copies, one for each logical CPU on the host. Programs running in the context of CPU#0 for example will see different map contents as a program running on CPU#2. Since multiple CPUs will never read or write to memory being accessed by another CPU, it is impossible for race conditions to occur, and thus programs don't need to waste cycles on mechanisms like spin-locks or atomic instructions to synchronize access. It also improves speed due to better cache locality. Another interesting use of these map types are as scratch buffers. Since eBPF programs always execute on the same logical CPU for their entire execution including tail calls, these maps can be used to transfer information between tail calls, something that is difficult to do otherwise. In the same spirit, these maps can also be used to hold data without counting towards the stack limit of the eBPF program. -When per-CPU maps are accessed via user-space all copies are always accesses at the same time. In fact the values read and written to these maps via the syscalls are like arrays with a size equal to the logical CPU count of the host. For more details, see the `BPF_MAP_LOOKUP_ELEM` and `BPF_MAP_UPDATE_ELEM` pages. +When per-CPU maps are accessed via user-space all copies are always accesses at the same time. In fact the values read and written to these maps via the syscalls are like arrays with a size equal to the logical CPU count of the host. For more details, see the [`BPF_MAP_LOOKUP_ELEM`](../syscall/BPF_MAP_LOOKUP_ELEM.md) and [`BPF_MAP_UPDATE_ELEM`](../syscall/BPF_MAP_UPDATE_ELEM.md) pages. The downside is that programs cannot share information across CPU boundaries. So these kinds of maps are typically better suited for use-cases where data flows from the programs to user space like counters or use-cases where related events always happen on the same logical CPU like incoming network packets of the same flow due to RSS diff --git a/docs/linux/program-type/index.md b/docs/linux/program-type/index.md index a76794e..c234cf4 100644 --- a/docs/linux/program-type/index.md +++ b/docs/linux/program-type/index.md @@ -13,7 +13,7 @@ These program types are triggered by network events * [`BPF_PROG_TYPE_SOCKET_FILTER`](BPF_PROG_TYPE_SOCKET_FILTER.md) * [`BPF_PROG_TYPE_SCHED_CLS`](BPF_PROG_TYPE_SCHED_CLS.md) -* `BPF_PROG_TYPE_SCHED_ACT` +* [`BPF_PROG_TYPE_SCHED_ACT`](BPF_PROG_TYPE_SCHED_ACT.md) * [`BPF_PROG_TYPE_XDP`](BPF_PROG_TYPE_XDP.md) * [`BPF_PROG_TYPE_SOCK_OPS`](BPF_PROG_TYPE_SOCK_OPS.md) * [`BPF_PROG_TYPE_SK_SKB`](BPF_PROG_TYPE_SK_SKB.md)