On Mon, Feb 12, 2024 at 4:49 PM Eduard Zingerman <eddyz87@xxxxxxxxx> wrote: > > On Mon, 2024-02-12 at 16:44 -0800, Alexei Starovoitov wrote: > > > I hit a strange bug when playing with patch. Consider a simple example [0]. > > > When the following BPF global variable: > > > > > > int __arena * __arena bar; > > > > > > - is commented -- the test passes; > > > - is uncommented -- in the test fails because global variable 'shared' is NULL. > > > > Right. That's expected, because __uint(max_entries, 1); > > The test creates an area on 1 page and it's consumed > > by int __arena * __arena bar; variable. > > Of course, one variable doesn't take the whole page. > > There could have been many arena global vars. > > But that page is not available anymore to bpf_arena_alloc_pages, > > so it returns NULL. > > My bad, thank you for explaining. Since it was a surprising behavior we can make libbpf to auto-extend max_entries with the number of pages necessary for arena global vars, but it will be surprising too. struct { __uint(type, BPF_MAP_TYPE_ARENA); __uint(map_flags, BPF_F_MMAPABLE); __ulong(map_extra, 2ull << 44); // this is start of user VMA __uint(max_entries, 1000); // this is length of user VMA in pages } arena SEC(".maps"); if libbpf adds extra pages to max_entries the user_vm_end shifts too and libbpf would need to mmap() it with that size. When all is hidden in libbpf it's fine, but still can be a surprise to see a different max_entries in map_info and bpftool map list. Not sure which way is user friendlier.