Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
UMA(9)		       FreeBSD Kernel Developer's Manual		UMA(9)

     UMA -- general-purpose kernel object allocator

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

     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_zcreate(char *name, int size, uma_ctor	ctor, uma_dtor dtor,
	 uma_init zinit, uma_fini zfini, int align, uint16_t flags);

     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_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor,
	 uma_init zinit, uma_fini zfini, uma_zone_t master);

     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);

     uma_zfree(uma_zone_t zone,	void *item);

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

     uma_zfree_pcpu(uma_zone_t zone, void *item);

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

     uma_prealloc(uma_zone_t zone, int nitems);

     uma_zone_reserve(uma_zone_t zone, int nitems);

     uma_zone_reserve_kva(uma_zone_t zone, int nitems);

     uma_reclaim(int req);

     uma_reclaim_domain(int req, int domain);

     uma_zone_reclaim(uma_zone_t zone, int req);

     uma_zone_reclaim_domain(uma_zone_t	zone, int req, int domain);

     uma_zone_set_allocf(uma_zone_t zone, uma_alloc allocf);

     uma_zone_set_freef(uma_zone_t zone, uma_free freef);

     uma_zone_set_max(uma_zone_t zone, int nitems);

     uma_zone_set_maxcache(uma_zone_t zone, int	nitems);

     uma_zone_get_max(uma_zone_t zone);

     uma_zone_get_cur(uma_zone_t zone);

     uma_zone_set_warning(uma_zone_t zone, const char *warning);

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


     #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);

     UMA (Universal Memory Allocator) provides an efficient interface for man-
     aging 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 re-
     quests.  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 respon-
     sible 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 im-
     port and release methods.	For example, some collections of kernel	ob-
     jects are statically allocated at boot-time, and the size of the collec-
     tion 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	debug-
     ging and stats; this memory should	not be freed until the zone has	been

     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() re-
     spectively.  Their	purpose	is to provide hooks for	initializing or	de-
     stroying things that need to be done at the time of the allocation	or re-
     lease 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	re-
     sponse 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, respec-
     tively.  The zimport function should store	pointers to items in the store
     array, which contains a maximum of	count entries.	The function must re-
     turn 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

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

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

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

	  An allocation	from zone would	have mp_ncpu shadow copies, that are
	  privately assigned to	CPUs.  A CPU can address its private copy us-
	  ing 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,	...);
		foo_pcpu = (foo_t *)zpcpu_get(foo_base);
		/* do something	with foo_pcpu */

	  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

	  The UMA subsystem may	not directly touch (i.e. read or write)	the
	  slab memory.	Otherwise, by default, book-keeping of items within a
	  slab may be done in the slab page itself, and	INVARIANTS kernels may
	  also do use-after-free checking by accessing the slab	memory.

	  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().

	  An allocator function	will be	supplied with uma_zone_set_allocf()
	  and the memory that it returns may not be kernel virtual memory
	  backed by VM pages in	the page array.

	  The zone is for the malloc(9)	subsystem.

	  The zone is for the VM subsystem.

	  Items	in this	zone must be contiguous	in physical address space.
	  Items	will follow normal alignment constraints and may span page
	  boundaries between pages with	contiguous physical addresses.

	  By default, UMA zone caches are shrunk to help resolve free page
	  shortages.  Cached items that	have not been used for a long period
	  may also be freed from zone.	When this flag is set, the system will
	  not reclaim memory from the zone's caches.

     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	spec-
     ify an argument for the ctor and dtor functions of	the zone, respec-
     tively.  The variants uma_zalloc_pcpu() and uma_zfree_pcpu() allocate and
     free mp_ncpu shadow copies	as described for UMA_ZONE_PCPU.	 If item is
     NULL, then	uma_zfree_pcpu() does nothing.

     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_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_reclaim() and uma_zone_reclaim() functions	reclaim	cached items
     from UMA zones, releasing unused memory.  The uma_reclaim() function re-
     claims items from all regular zones, while	uma_zone_reclaim() reclaims
     items only	from the specified zone.  The req parameter must be one	of
     three values which	specify	how aggressively items are to be reclaimed:

	     Reclaim items only	in excess of the zone's	estimated working set
	     size.  The	working	set size is periodically updated and tracks
	     the recent	history	of the zone's usage.

	     Reclaim all items from the	unbounded cache.  Free items in	the
	     per-CPU caches are	left alone.

	     Reclaim all cached	items.
     The uma_reclaim_domain() and uma_zone_reclaim_domain() functions apply
     only to items allocated from the specified	domain.	 In the	case of	do-
     mains using a round-robin NUMA policy, cached items from all domains are
     freed to the keg, but only	slabs from the specific	domain will be freed.

     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 memory with special constraints such as attributes, align-
     ment, or address ranges must 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.  This limit applies to both the per-CPU
     caches and	the cache of free buckets.

     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 approxi-
     mate 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 allo-
     cate 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.  There-
     fore, this	function should	do very	little work (similar to	a signal han-

     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 oc-
     cupancy 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.

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

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

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

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

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

     This manual page was written by Dag-Erling	Smorgrav <>.
     Changes for UMA by	Jeroen Ruigrok van der Werven <>.

FreeBSD	13.0		       February	15, 2022		  FreeBSD 13.0


Want to link to this manual page? Use this URL:

home | help