VMEM(9) Kernel Concepts VMEM(9)
NAME
vmem - virtual memory allocator
DESCRIPTION
Overview
An address space is divided into a number of logically distinct pieces,
or
arenas: text, data, heap, stack, and so on. Within these arenas we
often subdivide further; for example, we use heap addresses not only
for the kernel heap (
kmem_alloc() space), but also for DVMA,
bp_mapin(),
/dev/kmem, and even some device mappings.
The kernel address space, therefore, is most accurately described as a
tree of arenas in which each node of the tree
imports some subset of
its parent. The virtual memory allocator manages these arenas and
supports their natural hierarchical structure.
Arenas
An arena is nothing more than a set of integers. These integers most
commonly represent virtual addresses, but in fact they can represent
anything at all. For example, we could use an arena containing the
integers minpid through maxpid to allocate process IDs. For uses of
this nature, prefer
id_space(9F) instead.
vmem_create() and
vmem_destroy() create and destroy vmem arenas. In
order to differentiate between arenas used for addresses and arenas
used for identifiers, the VMC_IDENTIFIER flag is passed to
vmem_create(). This prevents identifier exhaustion from being
diagnosed as general memory failure.
Spans
We represent the integers in an arena as a collection of
spans, or
contiguous ranges of integers. For example, the kernel heap consists
of just one span: [kernelheap, ekernelheap). Spans can be added to an
arena in two ways: explicitly, by
vmem_add(); or implicitly, by
importing, as described in
Imported Memory below.
Segments
Spans are subdivided into
segments, each of which is either allocated
or free. A segment, like a span, is a contiguous range of integers.
Each allocated segment [addr, addr + size) represents exactly one
vmem_alloc(size) that returned
addr. Free segments represent the space
between allocated segments. If two free segments are adjacent, we
coalesce them into one larger segment; that is, if segments [a, b) and
[b, c) are both free, we merge them into a single segment [a, c). The
segments within a span are linked together in increasing-address order
so we can easily determine whether coalescing is possible.
Segments never cross span boundaries. When all segments within an
imported span become free, we return the span to its source.
Imported Memory
As mentioned in the overview, some arenas are logical subsets of other
arenas. For example,
kmem_va_arena (a virtual address cache that
satisfies most
kmem_slab_create() requests) is just a subset of
heap_arena (the kernel heap) that provides caching for the most common
slab sizes. When
kmem_va_arena runs out of virtual memory, it
imports more from the heap; we say that
heap_arena is the
vmem source for
kmem_va_arena. vmem_create() allows you to specify any existing vmem
arena as the source for your new arena. Topologically, since every
arena is a child of at most one source, the set of all arenas forms a
collection of trees.
Constrained Allocations
Some vmem clients are quite picky about the kind of address they want.
For example, the DVMA code may need an address that is at a particular
phase with respect to some alignment (to get good cache coloring), or
that lies within certain limits (the addressable range of a device), or
that doesn't cross some boundary (a DMA counter restriction) -- or all
of the above.
vmem_xalloc() allows the client to specify any or all of
these constraints.
The Vmem Quantum
Every arena has a notion of `quantum', specified at
vmem_create() time,
that defines the arena's minimum unit of currency. Most commonly the
quantum is either 1 or PAGESIZE, but any power of 2 is legal. All vmem
allocations are guaranteed to be quantum-aligned.
Relationship to the Kernel Memory Allocator
Every kmem cache has a vmem arena as its slab supplier. The kernel
memory allocator uses
vmem_alloc() and
vmem_free() to create and
destroy slabs.
SEE ALSO
id_space(9F),
vmem_add(9F),
vmem_alloc(9F),
vmem_contains(9F),
vmem_create(9F),
vmem_walk(9F) Jeff Bonwick and Jonathan Adams, "Magazines and vmem: Extending the
Slab Allocator to Many CPUs and Arbitrary Resources.",
Proceedings of the 2001 Usenix Conference,
http://www.usenix.org/event/usenix01/bonwick.html.
illumos January 18, 2017 illumos