Re: [PATCH bpf-next v7 06/11] libbpf: Add support for global percpu data
From: Andrii Nakryiko
Date: Wed Jun 24 2026 - 12:48:45 EST
On Tue, Jun 23, 2026 at 9:14 PM Leon Hwang <leon.hwang@xxxxxxxxx> wrote:
>
> On 24/6/26 06:45, Andrii Nakryiko wrote:
> > On Mon, Jun 22, 2026 at 7:37 AM Leon Hwang <leon.hwang@xxxxxxxxx> wrote:
> [...]
> >> @@ -5353,6 +5387,13 @@ bpf_object__populate_internal_map(struct bpf_object *obj, struct bpf_map *map)
> >> return err;
> >> }
> >> map->mmaped = mmaped;
> >> + } else if (is_percpu) {
> >> + if (mprotect(map->mmaped, mmap_sz, PROT_READ)) {
> >> + err = -errno;
> >> + pr_warn("map '%s': failed to mprotect() contents: %s\n",
> >> + bpf_map__name(map), errstr(err));
> >> + return err;
> >> + }
> >
> > hm... do we need to do this? what happens for LIBBPF_MAP_KCONFIG, do
> > we just null out the initial image? should we just do that here?
> > Basically what I am asking is how important it is to access initial
> > per-CPU image after load? What's the realistic use case for that?
> >
>
> This was suggested by you in v3:
> https://lore.kernel.org/bpf/CAEf4BzY9KeVeo2+6Ht1v3rL6UdwNxABZCSK1OZ_sD8qhpYZaeQ@xxxxxxxxxxxxxx/
>
ah, the dangling pointer in skeleton that needs clearing, I forgot
already :) ok, I don't mind mprotect(), it just was a new case that no
other map followed, so I was curious if we can avoid deviations. But
that brings back the KCONFIG map question, can you please check what's
happening for it? Maybe we should do the same mprotect instead of
dangling pointer (if we have dangling pointer, of course).
> >> } else if (map->mmaped) {
> >> munmap(map->mmaped, mmap_sz);
> >> map->mmaped = NULL;
> >> @@ -10806,16 +10847,19 @@ int bpf_map__fd(const struct bpf_map *map)
> >>
> >> static bool map_uses_real_name(const struct bpf_map *map)
> >> {
> >> - /* Since libbpf started to support custom .data.* and .rodata.* maps,
> >> - * their user-visible name differs from kernel-visible name. Users see
> >> - * such map's corresponding ELF section name as a map name.
> >> - * This check distinguishes .data/.rodata from .data.* and .rodata.*
> >> - * maps to know which name has to be returned to the user.
> >> + /*
> >> + * Since libbpf started to support custom .data.*, .rodata.* and
> >> + * .percpu.* maps, their user-visible name differs from
> >> + * kernel-visible name. Users see such map's corresponding ELF section
> >> + * name as a map name. This check distinguishes plain .data/.rodata/.percpu
> >> + * from .data.*, .rodata.* and .percpu.* to choose which name to return.
> >> */
> >> if (map->libbpf_type == LIBBPF_MAP_DATA && strcmp(map->real_name, DATA_SEC) != 0)
> >> return true;
> >> if (map->libbpf_type == LIBBPF_MAP_RODATA && strcmp(map->real_name, RODATA_SEC) != 0)
> >> return true;
> >> + if (map->libbpf_type == LIBBPF_MAP_PERCPU && strcmp(map->real_name, PERCPU_SEC) != 0)
> >> + return true;
> >
> > um... this is extra logic for DATA/RODATA is supposed to be backwards
> > compatible legacy stuff. We shouldn't need this for PERCPU_SEC. It
> > should actually be called just ".percpu", not "<object_name>.percpu".
> >
> Understand the backwards compatibility after reading the comment in
> internal_map_name().
>
> Will drop this hunk, and set "map->name" as ".percpu" in
> bpf_object__init_internal_map().
>
> Thanks,
> Leon
>