NAME
memoryallocators —
introduction to
kernel memory allocators
DESCRIPTION
The
NetBSD kernel provides several memory allocators,
each with different characteristics and purpose. This document summarizes the
main differences between them.
You should use the
kmem(9) allocator
for all allocations unless you have special needs that it does not provide,
such as:
- use from interrupt
handlers
- a minimum reserved number of
allocations
- a maximum usable number of
allocations
- costly object initialization
that can be reused
- allocating resources other
than pageable RAM-backed kernel virtual address space
The Kmem Allocator
The
kmem(9) allocator is main
general purpose allocator in the kernel. It was modelled after an interface of
the same name implemented in Solaris.
kmem(9) is fast and requires no
setup. It cannot be used from interrupt context.
Internally,
kmem(9) is implemented
using a collection of pool caches for common small allocation sizes, so there
is no performance benefit to using a pool cache if you have no other needs.
The Pool Allocator
The
pool(9) allocator is a
fixed-size memory allocator which requires setup to initialize a shared pool.
A pool can be configured with a low-water mark to reserve a minimum number of
objects available, a high-water mark to bound the maximum number of objects in
reserve, and a hard limit to bound on the maximum number of objects in use.
pool_get(9) can be used to
allocate memory in interrupt context for objects that have been reserved in
advance, with the possibility of failure if there are none.
By default,
pool(9) allocates
pageable RAM-backed kernel virtual address space from the same backing store
as
kmem(9), but it can be
configured to allocate any kind of resource with a custom allocator.
The Pool Cache Allocator
The pool cache allocator is a per-CPU cache on top of
pool(9) for fixed-size memory
allocations that may occur in interrupt context requiring setup beforehand.
The per-CPU cache makes allocation much cheaper — no interprocessor
synchronization in the fast case — at the cost of potentially caching
some extra resources on one CPU that cannot be used by another.
In addition to all the features of a pool like a custom backing allocator, a
pool cache also supports a constructor and destructor routine for when objects
are drawn from the shared pool in case the per-CPU cache is empty, or returned
to it when the cache is full. This can reduce the cost of reusable
initialization and finalization, or associate objects with CPU-local
resources.
The UVM Kernel Memory
Allocator
The
uvm_km(9) API is a low-level
memory allocator for page-aligned kernel virtual address space in multiples of
PAGE_SIZE
, with wired RAM backing, pageable RAM
backing, or backing to be supplied by the caller with
pmap(9).
The VMEM Allocator API
The
vmem(9) API is a general address
space allocator. It is used internally by
kmem(9),
pool(9),
uvm(9), and other kernel subsystems
and device drivers to allocate regions of various kinds of address spaces.
Internally, it allocates large chunks of the address space and uses a
pool_cache(9) to draw small
allocations out of them.
The Extent Manager
The
extent(9) API manages and
allocates constrained regions of an address space. The extent manager is
optimized for simplicity, not speed, and is available early at boot.
NetBSD uses
extent(9) to reserve regions of
I/O port and memory spaces to prevent drivers from using the same device
registers or bus memory.
SEE ALSO
bus_space(9),
extent(9),
intro(9),
kmem(9),
pool(9),
pool_cache(9),
uvm(9),
uvm_km(9),
vmem(9)
AUTHORS
Elad Efrat
<
elad@NetBSD.org>
YAMAMOTO Takashi
<
yamt@NetBSD.org>
Taylor R Campbell
<
riastradh@NetBSD.org>