Re: 5 gigs of contiguos kernel VM shared with userspace

Mark Johnston <[email protected]>
Newsgroups gmane.os.freebsd.devel.hackers
Message-ID <annstbB0TaeUjTkl@nuc>
On Mon, Aug 10, 2026 at 05:12:49AM +0300, Vadim Goncharov wrote:
> On Sun, 9 Aug 2026 19:15:59 -0400
> Mark Johnston <[email protected]> wrote:
> 
> > On Mon, Aug 10, 2026 at 01:32:02AM +0300, Vadim Goncharov wrote:
> > > Hello,
> > > 
> > > Are there ways to allocate in kernel a range of contiguous virtual address
> > > space, share it with userspace, and preferably run memory allocator inside
> > > it which has it's pointers relative to base address? Same as processes
> > > cooperating via mmap(), but for kernel<->user.
> > > 
> > > I'd like just run UMA inside it, but seems UMA zones cannot be told to take
> > > from particular range, or am I missing something? On user side, jemalloc
> > > mentions something like arenas, but seems it is too unprepared for even
> > > mmap() between processes case (may be adapting some TLSF allocator [*] is
> > > possible, but that's a premature question before VM one).  
> > 
> > UMA is really two fairly distinct things: a slab allocator, and a cache.
> > UMA zones provide per-CPU and per-NUMA domain caches, and UMA kegs
> > allocate and manage slabs.
> > 
> > You can have a zone without a keg: if you have some collection of
> > objects you want to allocate to consumers, you can use
> > uma_zcache_create() to create a "cache zone" which provides the usual
> > per-CPU etc. caches to store objects returned by a custom uz_import
> > callback that you provide when creating the zone.  For instance, if you
> > have some static array of objects (i.e., there is no need to subdivide a
> > slab) and just want to slap a scalable cache in front of it,
> > uma_zcache_create() is handy.
> > 
> > The other thing you could do is provide a custom slab allocator for the
> > keg via uma_zone_set_allocf().  There, you provide some page allocator,
> > and you can impose whatever constraints you want.  uma_small_alloc() is
> > used by default for page-sized slabs, and page_alloc() is used by
> 
> Is that all ported/portable to userspace?

No.  Most of it probably wouldn't be too bad.  I'd move some parts of it
to a uma_kern.c (e.g., uma_small_alloc() and page_alloc(), referenced
above, would live there).  But you'd also need to decide how per-CPU
caches should be implemented in userspace.

> > default for multi-page slabs.  Your implementation could return pages
> > from some pre-allocated, contiguous range of memory.
> 
> That's the main [prerequisite] question: how to do in kernel thing similar
> to mmap(0, 0x5000000, MAP_SHARED|MAP_ALIGNED_SUPER, ...) and share this
> region with userspace process(es).

It depends, I guess you want the region to be demand-paged?  If so,
something like:
1. kmem_subinit() to find some region of the kernel address space it can
   use to map the area.
2. Allocate a VM object.
3. Use vm_map_find() to allocate the kernel virtual address region from
   the submap, and to associate that region with your VM object.
4. Map that VM object into userspace as desired, e.g., by returning the
   VM object from some device node's d_mmap_single implementation.
5. Now the kernel and participating userspace programs can fault on
   their respective mappings of that VM object.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.