Re: [PATCH bpf-next 0/5] bpf: Expose pinned arenas as sized bpffs files

From: Andrii Nakryiko

Date: Fri Oct 16 2026 - 15:55:37 EST


On Fri, Oct 16, 2026 at 12:03 PM Alexei Starovoitov
<alexei.starovoitov@xxxxxxxxx> wrote:
>
> On Sun, Oct 11, 2026 at 12:45 AM Andrea Righi <arighi@xxxxxxxxxx> wrote:
> > The guest scheduler can create its own arena and allocate pages from
> > that NUMA node. Those guest physical pages are backed by the host arena,
> > so host and guest BPF programs can access the same memory through their
> > respective arenas.
>
> in addition to what Josh said...
>
> That node is ordinary RAM for the guest.
> When the guest scheduler exits arena_map_free() does __free_page() and
> the page goes back to the guest's buddy allocator. Nobody tells the host.
> The host prog keeps writing at that offset into whatever the guest
> allocates there next.
> NO_FREE in the guest doesn't help. It covers the kfunc only.
>
> Patch 5 needs a 16M node (256M on ppc) to get one page into the guest
> arena. Arena is 4G at most and it's one arena per prog, so that's
> 256 guests per host scheduler.
>
> The NUMA node is a way to avoid teaching arena to use pages that it
> didn't allocate. I think that's the missing piece in either model:
> host allocates -> guest arena is populated from a BAR,
> guest allocates -> host arena is populated from pinned guest pages.
> As Josh said the BAR is needed for the doorbell anyway.
>
> If arena can do that, can the host side take the pages from memfd
> with memfd_pin_folios() like udmabuf does ?
> VMM can map memfd at any address and offset already.
> Then no need for NO_FREE, EXPORT, sized file in bpffs, 2nd kind of vma
> in arena, etc.
>
> The loader does memfd_create() or opens a file in tmpfs, calls
> bpf_arena_import_memfd(&arena, addr, cnt, fd, off) from a syscall prog

As briefly discussed at LPC, I have nothing against adding support
like this to the arena.

But as I was reading Josh's reply and thinking about multiple VMs and
multiple vCPUs (that can also come and go), I kept thinking that it
sounds like a pretty good fit of map-of-maps and ARRAY maps, where key
for map-of-maps would be either entire VM or vCPU, whichever is more
convenient. What is missing here is the ability to create an ARRAY map
from memory that was already allocated before, instead of asking the
kernel to do that. But once we have the ability to create ARRAY from a
bunch of pre-existing memory (e.g., from memfd), this can be used both
in a guest and in the host, and both models, guest allocates or host
allocates, could be supported with the same model.

(regardless of this particular use case, I think it would be great to
be able to create ARRAY from memfd for some other potential use cases)

One disadvantage of ARRAY that was mentioned before is the need to
bounds check/limit access for PTR_TO_MAP_VALUE. I agree that's
annoying, but what if we teach verifier to just automatically add
bounds limiting sequence (e.g., masking if value size is power of two,
slightly slower sequence for non-power-of-two, of course) for all such
PTR_TO_MAP_VALUE accesses (e.g., if map is marked with some BPF_F_xxx
flag).

Is it doable? It would be great, if so. Arena's singleton nature and
4GB limitation might not be the right fit for all cases, so it would
be good to have an ARRAY-based solution available as well, IMO.

Thoughts?

> and gives the same file to QEMU the way patch 5 does with the pin.
> The imported pages stay until the arena is freed, so it's NO_FREE for
> the shared part only. libarena keeps working in the rest of the arena.
> arena_map_ext_pages() is what a BAR in the guest or pinned guest pages
> in the pvsched model would call.
> What is missing: user space has to mmap the memfd to see these pages.
> The arena vma gives SIGBUS there.
> Something like this (compile tested only):
>

[...]