Re: [PATCH bpf-next v12 06/10] bpftool: Generate skeleton for global percpu data
Andrii Nakryiko <[email protected]>
| Newsgroups | org.kernel.vger.linux-kselftest,org.kernel.vger.bpf,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAEf4BzYRqZ--=5d2LBWA=mOL72CYe4y4iCGS3c5Dw8PEd9BOiA@mail.gmail.com> |
On Thu, Aug 13, 2026 at 8:24 AM Leon Hwang <[email protected]> wrote: > > Enhance bpftool to generate skeletons that properly handle global percpu > variables. The generated skeleton now includes a dedicated structure for > percpu data, allowing users to initialize and access percpu variables more > efficiently. > > For global percpu variables, the skeleton now includes a nested > structure, e.g.: > > struct test_global_percpu_data { > struct bpf_object_skeleton *skeleton; > struct bpf_object *obj; > struct { > struct bpf_map *percpu; > } maps; > // ... > struct test_global_percpu_data__percpu { > int data; > char run; > struct { > char set; > int i; > int nums[7]; > } struct_data; > int nums[7]; > } *percpu; > > // ... > }; > > * The "struct test_global_percpu_data__percpu *percpu" points to > initialized data, which is actually "maps.percpu->mmaped". > * Before loading the skeleton, updating the > "struct test_global_percpu_data__percpu *percpu" modifies the initial > value of the corresponding global percpu variables. > * After loading the skeleton, "maps.percpu->mmaped" has been marked as > read-only in libbpf. If users want to update the global percpu > variables, they have to update the "maps.percpu" map instead. > * For lightweight skeleton, "lskel->percpu" will be protected by > "mprotect(p, sz, PROT_READ)". > * For subskeleton, those variables of global percpu data will be > skipped. > > Acked-by: Quentin Monnet <[email protected]> > Assisted-by: Codex:gpt-5.5-xhigh > Signed-off-by: Leon Hwang <[email protected]> > --- > tools/bpf/bpftool/gen.c | 53 +++++++++++++++++++++++++++-------- > tools/lib/bpf/skel_internal.h | 24 ++++++++++++++-- > 2 files changed, 63 insertions(+), 14 deletions(-) [...] > @@ -263,13 +269,24 @@ static bool is_mmapable_map(const struct bpf_map *map, char *buf, size_t sz) > return true; > } > > - if (!bpf_map__is_internal(map) || !(bpf_map__map_flags(map) & BPF_F_MMAPABLE)) > + if (!bpf_map__is_internal(map)) > return false; > > if (!get_map_ident(map, buf, sz)) > return false; > > - return true; > + if (bpf_map__map_flags(map) & BPF_F_MMAPABLE) > + return true; > + > + if (bpf_map__type(map) == BPF_MAP_TYPE_PERCPU_ARRAY) > + return bpf_map__btf_value_type_id(map) != 0; why do we need this btf_value_type_id() check? in what case it's expected that there will be no BTF info set? > + > + return false; > +} > + > +static bool is_mmapable_map(const struct bpf_map *map, char *buf, size_t sz) > +{ > + return is_skel_data(map, buf, sz) && bpf_map__type(map) != BPF_MAP_TYPE_PERCPU_ARRAY; > } > [...]