BPF gains global per-CPU variables in a .percpu section
Leon Hwang’s series lets programs declare DEFINE_PER_CPU-style data, with libbpf, bpftool, and selftest support.
Linux BPF is gaining first-class global per-CPU data, the kind ordinary kernel code has long expressed with DEFINE_PER_CPU and related macros.
Leon Hwang posted a twelfth revision of the work on the BPF mailing list. Programs may place variables in a ".percpu" section; the runtime backs them with a single-entry per-CPU array and uses per-CPU instructions where the architecture allows. Matching support lands in libbpf (including an early feature probe so loaders fail cleanly on older kernels), in bpftool-generated skeletons, and in selftests that cover init, lookup, iteration, and read-only direct access.
The drive came from tracing tools such as retsnoop and bpfsnoop. Those programs had been keeping per-CPU buffers in ordinary globals indexed by bpf_get_smp_processor_id(), or sharing a one-entry percpu_array map between callers and callees. Inlining that helper already trimmed some overhead on x86_64, but dedicated global per-CPU storage is simpler and avoids extra last-branch-record noise when capturing control flow. The same shared variables also ease passing per-CPU state across tail calls and freplace boundaries without an ad hoc map.
Skeleton users get a typed pointer into the map’s initial contents for setup before load. After load the mmap’d view is marked read-only, so later updates go through the map (including BPF_F_ALL_CPUS for lightweight skeletons). Architectures without per-CPU instruction support skip the feature; tests gate on the probe rather than failing there.