Re: [PATCH bpf-next v4 2/7] bpf: Introduce BPF_F_CPU and BPF_F_ALL_CPUS flags

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 27, 2025 at 9:45 AM Leon Hwang <leon.hwang@xxxxxxxxx> wrote:
>
> Introduce BPF_F_CPU and BPF_F_ALL_CPUS flags and the following internal
> helper functions for percpu maps:
>
> * bpf_percpu_copy_to_user: For lookup_elem and lookup_batch user APIs,
>   copy data to user-provided value pointer.
> * bpf_percpu_copy_from_user: For update_elem and update_batch user APIs,
>   copy data from user-provided value pointer.
> * bpf_map_check_cpu_flags: Check BPF_F_CPU, BPF_F_ALL_CPUS and cpu info in
>   flags.
>
> And, get the correct value size for these user APIs.
>
> Signed-off-by: Leon Hwang <leon.hwang@xxxxxxxxx>
> ---
>  include/linux/bpf.h            | 89 ++++++++++++++++++++++++++++++++--
>  include/uapi/linux/bpf.h       |  2 +
>  kernel/bpf/syscall.c           | 24 ++++-----
>  tools/include/uapi/linux/bpf.h |  2 +
>  4 files changed, 103 insertions(+), 14 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 512717d442c09..a83364949b64c 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -547,6 +547,56 @@ static inline void copy_map_value_long(struct bpf_map *map, void *dst, void *src
>         bpf_obj_memcpy(map->record, dst, src, map->value_size, true);
>  }
>
> +#ifdef CONFIG_BPF_SYSCALL
> +static inline void bpf_percpu_copy_to_user(struct bpf_map *map, void __percpu *pptr, void *value,
> +                                          u32 size, u64 flags)
> +{
> +       int current_cpu = raw_smp_processor_id();
> +       int cpu, off = 0;
> +
> +       if (flags & BPF_F_CPU) {
> +               cpu = flags >> 32;
> +               copy_map_value_long(map, value, cpu != current_cpu ? per_cpu_ptr(pptr, cpu) :
> +                                   this_cpu_ptr(pptr));
> +               check_and_init_map_value(map, value);

I'm not sure it's the question to you, but why would we
"check_and_init_map_value" when copying data to user space?... this is
so confusing...

> +       } else {
> +               for_each_possible_cpu(cpu) {
> +                       copy_map_value_long(map, value + off, per_cpu_ptr(pptr, cpu));
> +                       check_and_init_map_value(map, value + off);
> +                       off += size;
> +               }
> +       }
> +}
> +
> +void bpf_obj_free_fields(const struct btf_record *rec, void *obj);
> +
> +static inline void bpf_percpu_copy_from_user(struct bpf_map *map, void __percpu *pptr, void *value,
> +                                            u32 size, u64 flags)
> +{
> +       int current_cpu = raw_smp_processor_id();
> +       int cpu, off = 0;
> +       void *ptr;
> +
> +       if (flags & BPF_F_CPU) {
> +               cpu = flags >> 32;
> +               ptr = cpu == current_cpu ? this_cpu_ptr(pptr) : per_cpu_ptr(pptr, cpu);
> +               copy_map_value_long(map, ptr, value);
> +               bpf_obj_free_fields(map->record, ptr);
> +       } else {
> +               for_each_possible_cpu(cpu) {
> +                       copy_map_value_long(map, per_cpu_ptr(pptr, cpu), value + off);
> +                       /* same user-provided value is used if
> +                        * BPF_F_ALL_CPUS is specified, otherwise value is
> +                        * an array of per-cpu values.
> +                        */
> +                       if (!(flags & BPF_F_ALL_CPUS))
> +                               off += size;
> +                       bpf_obj_free_fields(map->record, per_cpu_ptr(pptr, cpu));
> +               }
> +       }
> +}
> +#endif

hm... these helpers are just here with no way to validate that they
generalize existing logic correctly... Do a separate patch where you
introduce this helper before adding per-CPU flags *and* make use of
them in existing code? Then we can check that you didn't introduce any
subtle differences? Then in this patch you can adjust helpers to
handle BPF_F_CPU and BPF_F_ALL_CPUS?

pw-bot: cr

[...]





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux