On Sat Aug 23, 2025 at 6:14 AM +08, Andrii Nakryiko wrote: > On Thu, Aug 21, 2025 at 9:08 AM Leon Hwang <leon.hwang@xxxxxxxxx> wrote: >> >> Introduce support for the BPF_F_ALL_CPUS flag in percpu_array maps to >> allow updating values for all CPUs with a single value. >> >> Introduce support for the BPF_F_CPU flag in percpu_array maps to allow >> updating value for specified CPU. >> >> This enhancement enables: >> >> * Efficient update values across all CPUs with a single value when >> BPF_F_ALL_CPUS is set for update_elem and update_batch APIs. >> * Targeted update or lookup for a specified CPU when BPF_F_CPU is set. >> >> The BPF_F_CPU flag is passed via: >> >> * map_flags of lookup_elem and update_elem APIs along with embedded cpu >> field. >> * elem_flags of lookup_batch and update_batch APIs along with embedded >> cpu field. >> >> Signed-off-by: Leon Hwang <leon.hwang@xxxxxxxxx> >> --- >> include/linux/bpf.h | 3 +- >> include/uapi/linux/bpf.h | 2 ++ >> kernel/bpf/arraymap.c | 56 ++++++++++++++++++++++++++-------- >> kernel/bpf/syscall.c | 27 ++++++++++------ >> tools/include/uapi/linux/bpf.h | 2 ++ >> 5 files changed, 67 insertions(+), 23 deletions(-) >> > > [...] > >> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c >> index 19f7f5de5e7dc..6251ac9bc7e42 100644 >> --- a/kernel/bpf/syscall.c >> +++ b/kernel/bpf/syscall.c >> @@ -131,9 +131,11 @@ bool bpf_map_write_active(const struct bpf_map *map) >> return atomic64_read(&map->writecnt) != 0; >> } >> >> -static u32 bpf_map_value_size(const struct bpf_map *map) >> +static u32 bpf_map_value_size(const struct bpf_map *map, u64 flags) >> { >> - if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || >> + if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY && (flags & (BPF_F_CPU | BPF_F_ALL_CPUS))) >> + return round_up(map->value_size, 8); > > this doesn't depend on the PERCPU_ARRAY map type, right? Any map for > which we allowed BPF_F_CPU or BPF_F_ALL_CPUS would use this formula? > (and if map doesn't support those flags, you should have filtered that > out earlier, no?) So maybe add this is first separate condition before > all this map type specific logic? > Right. I will remove this map type specific logic in next revision. >> + else if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || >> map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH || >> map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY || >> map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) >> @@ -314,7 +316,7 @@ static int bpf_map_copy_value(struct bpf_map *map, void *key, void *value, >> map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { >> err = bpf_percpu_hash_copy(map, key, value); >> } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { >> - err = bpf_percpu_array_copy(map, key, value); >> + err = bpf_percpu_array_copy(map, key, value, flags); >> } else if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) { >> err = bpf_percpu_cgroup_storage_copy(map, key, value); >> } else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) { >> @@ -1656,12 +1658,19 @@ static void *___bpf_copy_key(bpfptr_t ukey, u64 key_size) >> >> static int check_map_flags(struct bpf_map *map, u64 flags, bool check_flag) > > you are later moving this into bpf.h header, so do it in previous > patch early on, less unnecessary code churn and easier to review > actual changes to that function in subsequent patches > Ack. Thanks, Leon [...]