Allocator Basics
The kernel memory allocator's job is to parcel out regions of virtual memory
to other kernel subsystems (these are commonly called clients). This section explains the
basics of the allocator's operation and introduces some terms used later in this
guide.
Buffer States
The functional domain of the kernel memory allocator is the set of
buffers of virtual memory that make up the kernel heap. These buffers
are grouped together into sets of uniform size and purpose, known as caches.
Each cache contains a set of buffers. Some of these buffers
are currently free, which means that they have not yet been allocated to
any client of the allocator. The remaining buffers are allocated, which means
that a pointer to that buffer has been provided to a client of
the allocator. If no client of the allocator holds a pointer to
an allocated buffer, this buffer is said to be leaked, because it cannot
be freed. Leaked buffers indicate incorrect code that is wasting kernel resources.
Transactions
A kmem transaction is a transition on a buffer between the allocated and
free states. The allocator can verify that the state of a buffer
is valid as part of each transaction. Additionally, the allocator has facilities for
logging transactions for post-mortem examination.
Sleeping and Non-Sleeping Allocations
Unlike the Standard C Library's malloc(3C) function, the kernel memory allocator can block (or
sleep), waiting until enough virtual memory is available to satisfy the client's request.
This is controlled by the flag parameter to kmem_alloc(9F). A call to
kmem_alloc(9F) which has the KM_SLEEP flag set can never fail; it will block
forever waiting for resources to become available.
Kernel Memory Caches
The kernel memory allocator divides the memory it manages into a set of
caches. All allocations are supplied from these caches, which are represented by
the kmem_cache_t data structure. Each cache has a fixed buffer size, which represents the
maximum allocation size satisfied by that cache. Each cache has a string
name indicating the type of data it manages.
Some kernel memory caches are special purpose and are initialized to allocate only
a particular kind of data structure. An example of this is the
“thread_cache,” which allocates only structures of type kthread_t. Memory from these
caches is allocated to clients by the kmem_cache_alloc() function and freed by
the kmem_cache_free() function.
Note - kmem_cache_alloc() and kmem_cache_free() are not public DDI interfaces. Do NOT write code that
relies on them, because they are subject to change or removal in future
releases of Solaris.
Caches whose name begins with “kmem_alloc_” implement the kernel's general memory allocation scheme.
These caches provide memory to clients of kmem_alloc(9F) and kmem_zalloc(9F). Each of
these caches satisfies requests whose size is between the buffer size of that
cache and the buffer size of the next smallest cache. For example,
the kernel has kmem_alloc_8 and kmem_alloc_16 caches. In this case, the
kmem_alloc_16 cache handles all client requests for 9-16 bytes of memory. Remember
that the size of each buffer in the kmem_alloc_16 cache is 16 bytes,
regardless of the size of the client request. In a 14
byte request, two bytes of the resulting buffer are unused, since the request
is satisfied from the kmem_alloc_16 cache.
The last set of caches are those used internally by the kernel
memory allocator for its own bookkeeping. These include those caches whose names start
with “kmem_magazine_” or “kmem_va_”, the kmem_slab_cache, the kmem_bufctl_cache and others.