Introduce support for the BPF_F_ALL_CPUS flag in percpu_array maps to allow updating values for all CPUs with a single value for both update_elem and update_batch APIs. Introduce support for the BPF_F_CPU flag in percpu_array maps to allow: * update value for specified CPU for both update_elem and update_batch APIs. * lookup value for specified CPU for both lookup_elem and lookup_batch APIs. The BPF_F_CPU flag is passed via: * map_flags of lookup_elem and update_elem APIs along with embedded cpu info. * elem_flags of lookup_batch and update_batch APIs along with embedded cpu info. Signed-off-by: Leon Hwang --- include/linux/bpf.h | 7 ++++++- kernel/bpf/arraymap.c | 12 +++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index ef7f7c6a864c2..67122f852f16d 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -3754,7 +3754,12 @@ struct bpf_prog *bpf_prog_find_from_stack(void); static inline bool bpf_map_supports_cpu_flags(enum bpf_map_type map_type) { - return false; + switch (map_type) { + case BPF_MAP_TYPE_PERCPU_ARRAY: + return true; + default: + return false; + } } static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 allowed_flags) diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index d02cce3202840..93acd4c93a3a8 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -301,6 +301,11 @@ int bpf_percpu_array_copy(struct bpf_map *map, void *key, void *value, u64 map_f u32 index = *(u32 *)key; void __percpu *pptr; u32 size; + int err; + + err = bpf_map_check_cpu_flags(map_flags, false); + if (unlikely(err)) + return err; if (unlikely(index >= array->map.max_entries)) return -ENOENT; @@ -383,10 +388,11 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value, u32 index = *(u32 *)key; void __percpu *pptr; u32 size; + int err; - if (unlikely(map_flags > BPF_EXIST)) - /* unknown flags */ - return -EINVAL; + err = bpf_map_check_cpu_flags(map_flags, true); + if (unlikely(err)) + return err; if (unlikely(index >= array->map.max_entries)) /* all elements were pre-allocated, cannot insert a new one */ -- 2.50.1