Re: [PATCH bpf-next] bpf: add bpf_map_lookup_percpu_elem for percpu map

From: Yosry Ahmed
Date: Mon May 09 2022 - 21:05:20 EST


On Mon, May 9, 2022 at 5:34 PM Andrii Nakryiko
<andrii.nakryiko@xxxxxxxxx> wrote:
>
> On Fri, May 6, 2022 at 7:49 PM Feng zhou <zhoufeng.zf@xxxxxxxxxxxxx> wrote:
> >
> > From: Feng Zhou <zhoufeng.zf@xxxxxxxxxxxxx>
> >
> > Trace some functions, such as enqueue_task_fair, need to access the
> > corresponding cpu, not the current cpu, and bpf_map_lookup_elem percpu map
> > cannot do it. So add bpf_map_lookup_percpu_elem to accomplish it for
> > percpu_array_map, percpu_hash_map, lru_percpu_hash_map.
> >
> > The implementation method is relatively simple, refer to the implementation
> > method of map_lookup_elem of percpu map, increase the parameters of cpu, and
> > obtain it according to the specified cpu.
> >
>
> I don't think it's safe in general to access per-cpu data from another
> CPU. I'd suggest just having either a ARRAY_OF_MAPS or adding CPU ID
> as part of the key, if you need such a custom access pattern.

I actually just sent an RFC patch series containing a similar patch
for the exact same purpose. There are instances in the kernel where
per-cpu data is accessed from other cpus (e.g.
mem_cgroup_css_rstat_flush()). I believe, like any other variable,
percpu data can be safe or not safe to access, based on the access
pattern. It is up to the user to coordinate accesses to the variable.

For example, in my use case, one of the accessors only reads percpu
values of different cpus, so it should be safe. If a user accesses
percpu data of another cpu without guaranteeing safety, they corrupt
their own data. I understand that the main purpose of percpu data is
lockless (and therefore fast) access, but in some use cases the user
may be able to safely (and locklessly) access the data concurrently.

>
> > Signed-off-by: Feng Zhou <zhoufeng.zf@xxxxxxxxxxxxx>
> > ---
> > include/linux/bpf.h | 2 ++
> > include/uapi/linux/bpf.h | 9 +++++++++
> > kernel/bpf/arraymap.c | 15 +++++++++++++++
> > kernel/bpf/core.c | 1 +
> > kernel/bpf/hashtab.c | 32 ++++++++++++++++++++++++++++++++
> > kernel/bpf/helpers.c | 18 ++++++++++++++++++
> > kernel/bpf/verifier.c | 17 +++++++++++++++--
> > kernel/trace/bpf_trace.c | 2 ++
> > tools/include/uapi/linux/bpf.h | 9 +++++++++
> > 9 files changed, 103 insertions(+), 2 deletions(-)
> >
>
> [...]