Provided by: freebsd-manpages_12.2-1_all bug

NAME

     UMA — general-purpose kernel object allocator

SYNOPSIS

     #include <sys/param.h>
     #include <sys/queue.h>
     #include <vm/uma.h>
     options UMA_FIRSTTOUCH
     options UMA_XDOMAIN

     typedef int (*uma_ctor)(void *mem, int size, void *arg, int flags);
     typedef void (*uma_dtor)(void *mem, int size, void *arg);
     typedef int (*uma_init)(void *mem, int size, int flags);
     typedef void (*uma_fini)(void *mem, int size);
     typedef int (*uma_import)(void *arg, void **store, int count, int domain,
         int flags);
     typedef void (*uma_release)(void *arg, void **store, int count);
     typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, int domain,
         uint8_t *pflag, int wait);
     typedef void (*uma_free)(void *item, vm_size_t size, uint8_t pflag);

     uma_zone_t
     uma_zcreate(char *name, int size, uma_ctor ctor, uma_dtor dtor, uma_init zinit,
           uma_fini zfini, int align, uint16_t flags);

     uma_zone_t
     uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor, uma_init zinit,
           uma_fini zfini, uma_import zimport, uma_release zrelease, void *arg, int flags);

     uma_zone_t
     uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor, uma_init zinit, uma_fini zfini,
           uma_zone_t master);

     void
     uma_zdestroy(uma_zone_t zone);

     void *
     uma_zalloc(uma_zone_t zone, int flags);

     void *
     uma_zalloc_arg(uma_zone_t zone, void *arg, int flags);

     void *
     uma_zalloc_domain(uma_zone_t zone, void *arg, int domain, int flags);

     void *
     uma_zalloc_pcpu(uma_zone_t zone, int flags);

     void *
     uma_zalloc_pcpu_arg(uma_zone_t zone, void *arg, int flags);

     void
     uma_zfree(uma_zone_t zone, void *item);

     void
     uma_zfree_arg(uma_zone_t zone, void *item, void *arg);

     void
     uma_zfree_domain(uma_zone_t zone, void *item, void *arg);

     void
     uma_zfree_pcpu(uma_zone_t zone, void *item);

     void
     uma_zfree_pcpu_arg(uma_zone_t zone, void *item, void *arg);

     void
     uma_prealloc(uma_zone_t zone, int nitems);

     void
     uma_zone_reserve(uma_zone_t zone, int nitems);

     void
     uma_zone_reserve_kva(uma_zone_t zone, int nitems);

     void
     uma_zone_set_allocf(uma_zone_t zone, uma_alloc allocf);

     void
     uma_zone_set_freef(uma_zone_t zone, uma_free freef);

     int
     uma_zone_set_max(uma_zone_t zone, int nitems);

     int
     uma_zone_set_maxcache(uma_zone_t zone, int nitems);

     int
     uma_zone_get_max(uma_zone_t zone);

     int
     uma_zone_get_cur(uma_zone_t zone);

     void
     uma_zone_set_warning(uma_zone_t zone, const char *warning);

     void
     uma_zone_set_maxaction(uma_zone_t zone, void (*maxaction)(uma_zone_t));

     void
     uma_reclaim();

     #include <sys/sysctl.h>

     SYSCTL_UMA_MAX(parent, nbr, name, access, zone, descr);

     SYSCTL_ADD_UMA_MAX(ctx, parent, nbr, name, access, zone, descr);

     SYSCTL_UMA_CUR(parent, nbr, name, access, zone, descr);

     SYSCTL_ADD_UMA_CUR(ctx, parent, nbr, name, access, zone, descr);

DESCRIPTION

     UMA (Universal Memory Allocator) provides an efficient interface for managing dynamically-
     sized collections of items of identical size, referred to as zones.  Zones keep track of
     which items are in use and which are not, and UMA provides functions for allocating items
     from a zone and for releasing them back, making them available for subsequent allocation
     requests.  Zones maintain per-CPU caches with linear scalability on SMP systems as well as
     round-robin and first-touch policies for NUMA systems.  The number of items cached per CPU
     is bounded, and each zone additionally maintains an unbounded cache of items that is used to
     quickly satisfy per-CPU cache allocation misses.

     Two types of zones exist: regular zones and cache zones.  In a regular zone, items are
     allocated from a slab, which is one or more virtually contiguous memory pages that have been
     allocated from the kernel's page allocator.  Internally, slabs are managed by a UMA keg,
     which is responsible for allocating slabs and keeping track of their usage by one or more
     zones.  In typical usage, there is one keg per zone, so slabs are not shared among multiple
     zones.

     Normal zones import items from a keg, and release items back to that keg if requested.
     Cache zones do not have a keg, and instead use custom import and release methods.  For
     example, some collections of kernel objects are statically allocated at boot-time, and the
     size of the collection does not change.  A cache zone can be used to implement an efficient
     allocator for the objects in such a collection.

     The uma_zcreate() and uma_zcache_create() functions create a new regular zone and cache
     zone, respectively.  The uma_zsecond_create() function creates a regular zone which shares
     the keg of the zone specified by the master argument.  The name argument is a text name of
     the zone for debugging and stats; this memory should not be freed until the zone has been
     deallocated.

     The ctor and dtor arguments are callback functions that are called by the UMA subsystem at
     the time of the call to uma_zalloc() and uma_zfree() respectively.  Their purpose is to
     provide hooks for initializing or destroying things that need to be done at the time of the
     allocation or release of a resource.  A good usage for the ctor and dtor callbacks might be
     to initialize a data structure embedded in the item, such as a queue(3) head.

     The zinit and zfini arguments are used to optimize the allocation of items from the zone.
     They are called by the UMA subsystem whenever it needs to allocate or free items to satisfy
     requests or memory pressure.  A good use for the zinit and zfini callbacks might be to
     initialize and destroy a mutex contained within an item.  This would allow one to avoid
     destroying and re-initializing the mutex each time the item is freed and re-allocated.  They
     are not called on each call to uma_zalloc() and uma_zfree() but rather when an item is
     imported into a zone's cache, and when a zone releases an item to the slab allocator,
     typically as a response to memory pressure.

     For uma_zcache_create(), the zimport and zrelease functions are called to import items into
     the zone and to release items from the zone, respectively.  The zimport function should
     store pointers to items in the store array, which contains a maximum of count entries.  The
     function must return the number of imported items, which may be less than the maximum.
     Similarly, the store parameter to the zrelease function contains an array of count pointers
     to items.  The arg parameter passed to uma_zcache_create() is provided to the import and
     release functions.  The domain parameter to zimport specifies the requested numa(4) domain
     for the allocation.  It is either a NUMA domain number or the special value UMA_ANYDOMAIN.

     The flags argument of uma_zcreate() and uma_zcache_create() is a subset of the following
     flags:

     UMA_ZONE_NOFREE
          Slabs allocated to the zone's keg are never freed.

     UMA_ZONE_NODUMP
          Pages belonging to the zone will not be included in minidumps.

     UMA_ZONE_PCPU
          An allocation from zone would have mp_ncpu shadow copies, that are privately assigned
          to CPUs.  A CPU can address its private copy using base the allocation address plus a
          multiple of the current CPU ID and sizeof(struct pcpu):

                foo_zone = uma_zcreate(..., UMA_ZONE_PCPU);
                 ...
                foo_base = uma_zalloc(foo_zone, ...);
                 ...
                critical_enter();
                foo_pcpu = (foo_t *)zpcpu_get(foo_base);
                /* do something with foo_pcpu */
                critical_exit();

          Note that M_ZERO cannot be used when allocating items from a PCPU zone.  To obtain
          zeroed memory from a PCPU zone, use the uma_zalloc_pcpu() function and its variants
          instead, and pass M_ZERO.

     UMA_ZONE_OFFPAGE
          By default book-keeping of items within a slab is done in the slab page itself.  This
          flag explicitly tells subsystem that book-keeping structure should be allocated
          separately from special internal zone.  This flag requires either UMA_ZONE_VTOSLAB or
          UMA_ZONE_HASH, since subsystem requires a mechanism to find a book-keeping structure to
          an item being freed.  The subsystem may choose to prefer offpage book-keeping for
          certain zones implicitly.

     UMA_ZONE_ZINIT
          The zone will have its uma_init method set to internal method that initializes a new
          allocated slab to all zeros.  Do not mistake uma_init method with uma_ctor.  A zone
          with UMA_ZONE_ZINIT flag would not return zeroed memory on every uma_zalloc().

     UMA_ZONE_HASH
          The zone should use an internal hash table to find slab book-keeping structure where an
          allocation being freed belongs to.

     UMA_ZONE_VTOSLAB
          The zone should use special field of vm_page_t to find slab book-keeping structure
          where an allocation being freed belongs to.

     UMA_ZONE_MALLOC
          The zone is for the malloc(9) subsystem.

     UMA_ZONE_VM
          The zone is for the VM subsystem.

     UMA_ZONE_NUMA
          The zone should use a first-touch NUMA policy rather than the round-robin default.  If
          the UMA_FIRSTTOUCH kernel option is configured, all zones implicitly use a first-touch
          policy, and the UMA_ZONE_NUMA flag has no effect.  The UMA_XDOMAIN kernel option, when
          configured, causes UMA to do the extra tracking to ensure that allocations from first-
          touch zones are always local.  Otherwise, consumers that do not free memory on the same
          domain from which it was allocated will cause mixing in per-CPU caches.  See numa(4)
          for more details.

     Zones can be destroyed using uma_zdestroy(), freeing all memory that is cached in the zone.
     All items allocated from the zone must be freed to the zone before the zone may be safely
     destroyed.

     To allocate an item from a zone, simply call uma_zalloc() with a pointer to that zone and
     set the flags argument to selected flags as documented in malloc(9).  It will return a
     pointer to an item if successful, or NULL in the rare case where all items in the zone are
     in use and the allocator is unable to grow the zone and M_NOWAIT is specified.

     Items are released back to the zone from which they were allocated by calling uma_zfree()
     with a pointer to the zone and a pointer to the item.  If item is NULL, then uma_zfree()
     does nothing.

     The variants uma_zalloc_arg() and uma_zfree_arg() allow callers to specify an argument for
     the ctor and dtor functions of the zone, respectively.  The uma_zalloc_domain() function
     allows callers to specify a fixed numa(4) domain to allocate from.  This uses a guaranteed
     but slow path in the allocator which reduces concurrency.  The uma_zfree_domain() function
     should be used to return memory allocated in this fashion.  This function infers the domain
     from the pointer and does not require it as an argument.

     The uma_prealloc() function allocates slabs for the requested number of items, typically
     following the initial creation of a zone.  Subsequent allocations from the zone will be
     satisfied using the pre-allocated slabs.  Note that slab allocation is performed with the
     M_WAITOK flag, so uma_prealloc() may sleep.

     The uma_zone_reserve() function sets the number of reserved items for the zone.
     uma_zalloc() and variants will ensure that the zone contains at least the reserved number of
     free items.  Reserved items may be allocated by specifying M_USE_RESERVE in the allocation
     request flags.  uma_zone_reserve() does not perform any pre-allocation by itself.

     The uma_zone_reserve_kva() function pre-allocates kernel virtual address space for the
     requested number of items.  Subsequent allocations from the zone will be satisfied using the
     pre-allocated address space.  Note that unlike uma_zone_reserve(), uma_zone_reserve_kva()
     does not restrict the use of the pre-allocation to M_USE_RESERVE requests.

     The uma_zone_set_allocf() and uma_zone_set_freef() functions allow a zone's default slab
     allocation and free functions to be overridden.  This is useful if the zone's items have
     special memory allocation constraints.  For example, if multi-page objects are required to
     be physically contiguous, an allocf function which requests contiguous memory from the
     kernel's page allocator may be used.

     The uma_zone_set_max() function limits the number of items (and therefore memory) that can
     be allocated to zone.  The nitems argument specifies the requested upper limit number of
     items.  The effective limit is returned to the caller, as it may end up being higher than
     requested due to the implementation rounding up to ensure all memory pages allocated to the
     zone are utilised to capacity.  The limit applies to the total number of items in the zone,
     which includes allocated items, free items and free items in the per-cpu caches.  On systems
     with more than one CPU it may not be possible to allocate the specified number of items even
     when there is no shortage of memory, because all of the remaining free items may be in the
     caches of the other CPUs when the limit is hit.

     The uma_zone_set_maxcache() function limits the number of free items which may be cached in
     the zone, excluding the per-CPU caches, which are bounded in size.  For example, to
     implement a ‘pure’ per-CPU cache, a cache zone may be configured with a maximum cache size
     of 0.

     The uma_zone_get_max() function returns the effective upper limit number of items for a
     zone.

     The uma_zone_get_cur() function returns an approximation of the number of items currently
     allocated from the zone.  The returned value is approximate because appropriate
     synchronisation to determine an exact value is not performed by the implementation.  This
     ensures low overhead at the expense of potentially stale data being used in the calculation.

     The uma_zone_set_warning() function sets a warning that will be printed on the system
     console when the given zone becomes full and fails to allocate an item.  The warning will be
     printed no more often than every five minutes.  Warnings can be turned off globally by
     setting the vm.zone_warnings sysctl tunable to 0.

     The uma_zone_set_maxaction() function sets a function that will be called when the given
     zone becomes full and fails to allocate an item.  The function will be called with the zone
     locked.  Also, the function that called the allocation function may have held additional
     locks.  Therefore, this function should do very little work (similar to a signal handler).

     The SYSCTL_UMA_MAX(parent, nbr, name, access, zone, descr) macro declares a static sysctl(9)
     oid that exports the effective upper limit number of items for a zone.  The zone argument
     should be a pointer to uma_zone_t.  A read of the oid returns value obtained through
     uma_zone_get_max().  A write to the oid sets new value via uma_zone_set_max().  The
     SYSCTL_ADD_UMA_MAX(ctx, parent, nbr, name, access, zone, descr) macro is provided to create
     this type of oid dynamically.

     The SYSCTL_UMA_CUR(parent, nbr, name, access, zone, descr) macro declares a static read-only
     sysctl(9) oid that exports the approximate current occupancy of the zone.  The zone argument
     should be a pointer to uma_zone_t.  A read of the oid returns value obtained through
     uma_zone_get_cur().  The SYSCTL_ADD_UMA_CUR(ctx, parent, nbr, name, zone, descr) macro is
     provided to create this type of oid dynamically.

IMPLEMENTATION NOTES

     The memory that these allocation calls return is not executable.  The uma_zalloc() function
     does not support the M_EXEC flag to allocate executable memory.  Not all platforms enforce a
     distinction between executable and non-executable memory.

SEE ALSO

     numa(4), vmstat(8), malloc(9)

     Jeff Bonwick, The Slab Allocator: An Object-Caching Kernel Memory Allocator, 1994.

HISTORY

     The zone allocator first appeared in FreeBSD 3.0.  It was radically changed in FreeBSD 5.0
     to function as a slab allocator.

AUTHORS

     The zone allocator was written by John S. Dyson.  The zone allocator was rewritten in large
     parts by Jeff Roberson <jeff@FreeBSD.org> to function as a slab allocator.

     This manual page was written by Dag-Erling Smørgrav <des@FreeBSD.org>.  Changes for UMA by
     Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org>.