[PATCH bpf 0/2] bpf: fix per-cpu initialization of a BPF_F_CPU created hash element

From: Donggeun Yoo

Date: Sun Sep 20 2026 - 05:45:28 EST


A BPF_F_CPU update that creates a [lru_]percpu_hash element writes the
named CPU's slot and leaves the others holding the values of whatever
element was recycled into it, so a lookup of the new key returns a
deleted key's per-cpu values.

Patch 1 zero-fills the other CPUs. Patch 2 adds the selftest: the
existing cpu_flag subtests always prime a key with BPF_F_ALL_CPUS
first, so the element always exists by the time the flag is used and
the create path is not covered today.

Tested on x86_64 under QEMU/KVM, 4 vCPUs, on bpf/master a11212910cf0,
configured from the selftests' own fragments (config, config.vm,
config.x86_64):

test_progs -t percpu_alloc,map_init,htab_update,htab_mem,for_each,
map_kptr,map_ptr,map_in_map,lru_bug,map_lookup_percpu_elem,
map_percpu_stats,batch_map_ops,htab_reuse,timer,task_work

without patch 1 31/112 PASSED, 0 SKIPPED, 1/3 FAILED
with patch 1 32/115 PASSED, 0 SKIPPED, 0/0 FAILED

The three failures are the new subtests, one per allocation mode:

#304/18 percpu_alloc/cpu_flag_create_percpu_hash:FAIL
#304/19 percpu_alloc/cpu_flag_create_percpu_hash_malloc:FAIL
#304/20 percpu_alloc/cpu_flag_create_lru_percpu_hash:FAIL
test_percpu_map_cpu_flag_create:FAIL:value on specified cpu
unexpected value on specified cpu: actual 3735929054 != expected 0

3735929054 is 0xdeadc0de, the value the deleted key left behind. The
BPF_F_NO_PREALLOC case reproduces as reliably as the preallocated ones:
five runs of each arm, five failures without the patch and five passes
with it.

Donggeun Yoo (2):
bpf: Zero-fill other CPUs when BPF_F_CPU creates a per-cpu hash
element
selftests/bpf: Test per-cpu initialization of a BPF_F_CPU created
element

kernel/bpf/hashtab.c | 6 +-
.../selftests/bpf/prog_tests/percpu_alloc.c | 74 +++++++++++++++++++
2 files changed, 77 insertions(+), 3 deletions(-)

--
2.53.0