On Thu Aug 28, 2025 at 7:18 AM +08, Andrii Nakryiko wrote: > On Wed, Aug 27, 2025 at 9:46 AM Leon Hwang <leon.hwang@xxxxxxxxx> wrote: >> >> Add libbpf support for the BPF_F_CPU flag for percpu maps by embedding the >> cpu info into the high 32 bits of: >> >> 1. **flags**: bpf_map_lookup_elem_flags(), bpf_map__lookup_elem(), >> bpf_map_update_elem() and bpf_map__update_elem() >> 2. **opts->elem_flags**: bpf_map_lookup_batch() and >> bpf_map_update_batch() >> >> And the flag can be BPF_F_ALL_CPUS, but cannot be >> 'BPF_F_CPU | BPF_F_ALL_CPUS'. >> >> Behavior: >> >> * If the flag is BPF_F_ALL_CPUS, the update is applied across all CPUs. >> * If the flag is BPF_F_CPU, it updates value only to the specified CPU. >> * If the flag is BPF_F_CPU, lookup value only from the specified CPU. >> * lookup does not support BPF_F_ALL_CPUS. >> >> Signed-off-by: Leon Hwang <leon.hwang@xxxxxxxxx> >> --- >> tools/lib/bpf/bpf.h | 8 ++++++++ >> tools/lib/bpf/libbpf.c | 33 +++++++++++++++++++++++++++------ >> tools/lib/bpf/libbpf.h | 21 ++++++++------------- >> 3 files changed, 43 insertions(+), 19 deletions(-) >> > > [...] > >> @@ -10629,6 +10629,27 @@ static int validate_map_op(const struct bpf_map *map, size_t key_sz, >> case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE: { >> int num_cpu = libbpf_num_possible_cpus(); >> size_t elem_sz = roundup(map->def.value_size, 8); >> + __u32 cpu; >> + >> + if (flags & (BPF_F_CPU | BPF_F_ALL_CPUS)) { >> + if ((flags & BPF_F_CPU) && (flags & BPF_F_ALL_CPUS)) { >> + pr_warn("map '%s': can't use BPF_F_CPU and BPF_F_ALL_CPUS at the same time\n", >> + map->name); >> + return -EINVAL; >> + } >> + cpu = flags >> 32; >> + if (cpu >= num_cpu) { > > only check this if BPF_F_CPU is set > >> + pr_warn("map '%s': cpu %u in flags cannot be GE num cpus %d\n", > > "GE"? maybe "CPU #%d is not valid"... (or don't even check cpu value > itself, it's unlikely user using BPF_F_CPU will get it so wrong) > Let's remove it instead. Thanks, Leon