Part 8 10 chapters

Advanced kernel surface

The modern (2024โ€“2026) BPF feature set: kfuncs, BPF tokens, workqueues, struct_ops, dynptr, BPF arenas, iterators, and user ring buffers.

Chapter 48

Detaching and pinning: outliving the loader

Open the advanced part with the lifecycle question every earlier chapter dodged: what happens to a program when its loader exits? Learn how BPF objects are reference-counted, pin a program, map, and link to bpffs so they survive the loader, read the pinned map from a separate process, and detach by removing the pin.

40 minutesRead โ†’
Chapter 49

Syscall programs: when BPF loads BPF

A program type with no hook: BPF_PROG_TYPE_SYSCALL programs run on demand and can call the bpf() syscall themselves via bpf_sys_bpf. Understand loader programs โ€” a 'strace of libbpf' replayed in-kernel โ€” and the light skeletons bpftool builds from them, the path toward libbpf-free and signed program loading.

35 minutesRead โ†’
Chapter 50

The user ring buffer: a channel into BPF

Every ring buffer so far carried data kernel-to-user. The user ring buffer runs the other way: user space is the producer and the BPF program is the consumer, draining submitted samples with bpf_user_ringbuf_drain and a callback. Learn when to reach for it over a plain map, and meet the dynptr that each sample arrives as.

40 minutesRead โ†’
Chapter 51

Userspace eBPF: the same bytecode, no kernel

eBPF is a portable bytecode ISA, and it doesn't need the kernel. Run an eBPF program in a user-space VM with the Rust rbpf crate โ€” interpreter and JIT, with a Rust helper the bytecode calls โ€” needing no root, no kernel, not even the lab VM. Then meet bpftime, the runtime that accelerates uprobes in user space.

35 minutesRead โ†’
Chapter 52

kfuncs: calling the kernel, the modern way

The BPF helper list froze, so the kernel grew a better mechanism: kfuncs โ€” real kernel functions exposed to BPF through BTF, with typed pointer arguments and per-function flags. Understand why helpers stopped scaling, how the KF_ACQUIRE/KF_RELEASE/KF_RET_NULL/KF_TRUSTED_ARGS flags let the verifier reason about kernel objects, and write an Aya program that looks up a task by pid and is forced to release it.

45 minutesRead โ†’
Chapter 53

The BPF token: delegating BPF into containers

Loading BPF has always demanded capabilities in the init namespace โ€” all or nothing for a container. The BPF token (kernel 6.9) breaks that open: a privileged runtime mounts a bpffs with four delegation axes, a trusted unprivileged container derives a token from it, and the kernel checks the token instead of init-namespace capabilities. Learn the capability problem it solves, the delegation model, and where it plugs into Aya.

40 minutesRead โ†’
Chapter 54

Timers and workqueues: deferred work in the kernel

A BPF program runs to completion and cannot sleep or loop forever โ€” so how does it do something later, or periodically, or move expensive work off a hot probe? BPF timers (kernel 5.15) fire a callback in softirq context and can re-arm themselves; BPF workqueues (kernel 6.10) run a sleepable callback in process context. Learn the init/set_callback/start lifecycle, build an in-kernel periodic aggregator, and know when to reach for each.

45 minutesRead โ†’
Chapter 55

struct_ops: BPF that implements the kernel

Most BPF observes or filters at a hook the kernel calls. struct_ops inverts that: the kernel defines an interface โ€” a struct of function pointers โ€” and BPF supplies the whole implementation, which the kernel then calls into like a built-in module. Understand the vtable model behind Part 6's schedulers, write a minimal TCP congestion-control algorithm in BPF, and see the same mechanism reused across the kernel.

45 minutesRead โ†’
Chapter 56

Dynptrs and arenas: flexible memory for BPF

Classic BPF memory is rigid: fixed-size maps, fixed-size stack, bounds the verifier can prove at compile time. Two modern primitives loosen that. A dynptr is a verifier-tracked handle to a variable-length region โ€” the thing the user ring buffer handed you. A BPF arena is a sparse memory region shared zero-copy with user space, where BPF builds real pointer-based data structures. Learn both, and when each earns its place.

45 minutesRead โ†’
Chapter 57

BPF iterators: walking the kernel

Closing the advanced part with one more inversion. Instead of reacting to an event, a BPF iterator is the body of an in-kernel loop: the kernel walks a set โ€” every task, every socket, every map entry โ€” and calls your program once per element, which emits through a seq_file you can cat. Learn the iterator program type, the open-coded iterators that put bounded loops anywhere, and why pushing iteration into the kernel beats dragging state to user space.

40 minutesRead โ†’