Updated: 2022/Sep/29

Please read Privacy Policy. It's for your privacy.


VMEM(9)                    Kernel Developer's Manual                   VMEM(9)

NAME
     vmem - virtual memory allocator

SYNOPSIS
     #include <sys/vmem.h>

     vmem_t *
     vmem_create(const char *name, vmem_addr_t base, vmem_size_t size,
         vmem_size_t quantum,
         int (*allocfn)(void *, vmem_size_t, vm_flag_t, vmem_addr_t *),
         void (*freefn)(void *, vmem_addr_t, vmem_size_t), void *arg,
         vmem_size_t qcache_max, vm_flag_t flags, int ipl);

     vmem_t *
     vmem_xcreate(const char *name, vmem_addr_t base, vmem_size_t size,
         vmem_size_t quantum,
         int (*allocfn)(void *, vmem_size_t, vmem_size_t
         *, vm_flag_t, vmem_addr_t *),
         void (*freefn)(void *, vmem_addr_t, vmem_size_t), void *arg,
         vmem_size_t qcache_max, vm_flag_t flags, int ipl);

     int
     vmem_add(vmem_t *vm, vmem_addr_t addr, vmem_size_t size,
         vm_flag_t flags);

     int
     vmem_xalloc(vmem_t *vm, vmem_size_t size, vmem_size_t align,
         vmem_size_t phase, vmem_size_t nocross, vmem_addr_t minaddr,
         vmem_addr_t maxaddr, vm_flag_t flags, vmem_addr_t *addrp);

     int
     vmem_xalloc_addr(vmem_t *vm, vmem_addr_t addr, vmem_size_t size,
         vm_flag_t flags);

     void
     vmem_xfree(vmem_t *vm, vmem_addr_t addr, vmem_size_t size);

     void
     vmem_xfreeall(vmem_t *vm);

     int
     vmem_alloc(vmem_t *vm, vmem_size_t size, vm_flag_t flags,
         vmem_addr_t *addrp);

     void
     vmem_free(vmem_t *vm, vmem_addr_t addr, vmem_size_t size);

     void
     vmem_destroy(vmem_t *vm);

DESCRIPTION
     The vmem is a general purpose resource allocator.  Despite its name, it
     can be used for arbitrary resources other than virtual memory.

     vmem_create() creates a new vmem arena.

           name        The string to describe the vmem.

           base        The start address of the initial span.  Pass 0 if no
                       initial span is required.

           size        The size of the initial span.  Pass 0 if no initial
                       span is required.

           quantum     The smallest unit of allocation.

           allocfn     The callback function used to import spans from the
                       backend arena.  Set both allocfn and freefn to NULL to
                       disable automatic imports.  vmem calls (*allocfn)(arg,
                       size, flags, &addrp) to import a span of size at least
                       size.  allocfn must accept the same flags as
                       vmem_alloc().  allocfn must return ENOMEM to indicate
                       failure, or 0 on success.  If allocfn succeeds, it must
                       write the starting address of the imported span to
                       addrp.

           freefn      The callback function used to free spans to the backend
                       arena.  freefn may be NULL even if allocfn is not NULL.
                       vmem calls (*freefn)(arg, addr, size) to return to arg
                       a span of size size, starting at addr, that was
                       previously allocated by allocfn.

           arg         The backend arena.  arg may be NULL.  vmem passes arg
                       as the first argument of allocfn and freefn.

           qcache_max  The largest size of allocations which can be served by
                       quantum cache.  It is merely a hint and can be ignored.

           flags       Either of:

                       VM_SLEEP    If the allocation cannot be satisfied
                                   immediately, sleep until enough resources
                                   are available.

                       VM_NOSLEEP  Don't sleep.  Immediately return NULL if
                                   there are not enough resources available.

           ipl         Interrupt level to be blocked for allocating from vmem.

     vmem_xcreate() creates a new vmem arena.

           name        The string to describe the vmem.

           base        The start address of the initial span.  Pass 0 if no
                       initial span is required.

           size        The size of the initial span.  Pass 0 if no initial
                       span is required.

           quantum     The smallest unit of allocation.

           allocfn     The callback function used to import spans from the
                       backend arena.  Set both allocfn and freefn to NULL to
                       disable automatic imports.  vmem calls (*allocfn)(arg,
                       size, &actualsize, flags, &addrp) to import a span of
                       size at least size.  allocfn must accept the same flags
                       as vmem_alloc().  allocfn must return ENOMEM to
                       indicate failure, or 0 on success.  If allocfn
                       succeeds, it must write the actual size of the
                       allocation to actualsize and the starting address of
                       the imported span to addrp.  The actual size will
                       always be greater than or equal to the requested size.

           freefn      The callback function used to free spans to the backend
                       arena.  freefn may be NULL even if allocfn is not NULL.
                       vmem calls (*freefn)(arg, addr, size) to return to arg
                       a span of size size, starting at addr, that was
                       previously allocated by allocfn.

           arg         The backend arena.  arg may be NULL.  vmem passes arg
                       as the first argument of allocfn and freefn.

           qcache_max  The largest size of allocations which can be served by
                       quantum cache.  It is merely a hint and can be ignored.

           flags       Either of:

                       VM_SLEEP    If the allocation cannot be satisfied
                                   immediately, sleep until enough resources
                                   are available.

                       VM_NOSLEEP  Don't sleep.  Immediately return NULL if
                                   there are not enough resources available.

           ipl         Interrupt level to be blocked for allocating from vmem.

     vmem_add() adds a span of size size starting at addr to the arena.
     Returns 0 on success, ENOMEM on failure.

           flags  Either of:

                  VM_SLEEP    If the allocation cannot be satisfied
                              immediately, sleep until enough resources are
                              available.

                  VM_NOSLEEP  Don't sleep.  Immediately return ENOMEM if there
                              are not enough resources available.

     vmem_xalloc() allocates a resource from the arena.

           vm       The arena which we allocate from.

           size     Specify the size of the allocation.

           align    If zero, don't care about the alignment of the allocation.
                    Otherwise, request a resource segment starting at offset
                    phase from an align aligned boundary.

           phase    See the above description of align.  If align is zero,
                    phase must be zero.  Otherwise, phase must be smaller than
                    align.

           nocross  Request a resource which doesn't cross nocross aligned
                    boundary.

           minaddr  Specify the minimum address which can be allocated, or
                    VMEM_ADDR_MIN if the caller does not care.

           maxaddr  Specify the maximum address which can be allocated, or
                    VMEM_ADDR_MAX if the caller does not care.

           flags    A bitwise OR of an allocation strategy and a sleep flag.

                    The allocation strategy must be one of:

                    VM_BESTFIT     Prefer space efficiency.

                    VM_INSTANTFIT  Prefer performance.

                    The sleep flag must be one of:

                    VM_SLEEP    If the allocation cannot be satisfied
                                immediately, sleep until enough resources are
                                available.

                    VM_NOSLEEP  Don't sleep.  Immediately return ENOMEM if
                                there are not enough resources available.

           addrp    On success, if addrp is not NULL, vmem_xalloc() overwrites
                    it with the start address of the allocated span.

     vmem_xalloc_addr() allocates a specific address from the arena.  The
     requested address must be aligned with the arena's quantum.

           vm     The arena which we allocate from.

           addr   The address to allocate.

           size   Specify the size of the allocation.

           flags  A sleep flag.  Because a specific address is being
                  allocated, any specified allocation strategy is ignored.

                  The sleep flag must be one of:

                  VM_SLEEP    If the allocation cannot be satisfied
                              immediately, sleep until the requested range can
                              be allocated.

                  VM_NOSLEEP  Don't sleep.  Immediately return ENOMEM if the
                              requested range is not available.

     vmem_xfree() frees resource allocated by vmem_xalloc() or
     vmem_xalloc_addr() to the arena.

           vm    The arena which we free to.

           addr  The resource being freed.  It must have been allocated via
                 vmem_xalloc() or vmem_xalloc_addr().  Notably, it must not
                 have been allocated via vmem_alloc(), otherwise, the
                 behaviour is undefined.

           size  The size of the resource being freed.  It must be the same as
                 the size argument used for vmem_xalloc() or
                 vmem_xalloc_addr().

     vmem_xfreeall() frees all resources that have been allocated by
     vmem_xalloc() to the arena.

           vm    The arena which we free to.  Note that this function is may
                 not be used on arenas where resources have been allocated
                 using vmem_alloc() or arenas that have a quantum cache (i.e.
                 were created with a non-zero qcache_max).

     vmem_alloc() allocates a resource from the arena.

           vm     The arena which we allocate from.

           size   Specify the size of the allocation.

           flags  A bitwise OR of an allocation strategy and a sleep flag.

                  The allocation strategy must be one of:

                  VM_BESTFIT     Prefer space efficiency.

                  VM_INSTANTFIT  Prefer performance.

                  The sleep flag must be one of:

                  VM_SLEEP    If the allocation cannot be satisfied
                              immediately, sleep until enough resources are
                              available.

                  VM_NOSLEEP  Don't sleep.  Immediately return ENOMEM if there
                              are not enough resources available.

           addrp  On success, if addrp is not NULL, vmem_alloc() overwrites it
                  with the start address of the allocated span.

     vmem_free() frees resource allocated by vmem_alloc() to the arena.

           vm    The arena which we free to.

           addr  The resource being freed.  It must have been allocated via
                 vmem_alloc().  Notably, it must not have been allocated via
                 vmem_xalloc() or vmem_xalloc(addr), otherwise, the behaviour
                 is undefined.

           size  The size of the resource being freed.  It must be the same as
                 the size argument used for vmem_alloc().

     vmem_destroy() destroys a vmem arena.

           vm  The vmem arena being destroyed.  The caller must ensure that no
               one will use it anymore.

RETURN VALUES
     vmem_create() and vmem_xcreate() return a pointer to the newly allocated
     vmem_t on success, or NULL if VM_NOSLEEP was specified and memory could
     not be allocated immediately.

     vmem_add() returns 0 on success, or ENOMEM if VM_NOSLEEP was specified
     and memory could not be allocated immediately to record the region.

     vmem_alloc() and vmem_xalloc() return 0 on success, or ENOMEM if either:

     -   VM_NOSLEEP was specified and a matching region could not be allocated
         immediately; or

     -   non-default align, phase, or nocross parameters were specified, and a
         matching region could not be allocated without calling the backing
         allocfn passed to vmem_create().

CODE REFERENCES
     The vmem subsystem is implemented within the file sys/kern/subr_vmem.c.

SEE ALSO
     intro(9), kmem(9), memoryallocators(9), uvm(9)

     Jeff Bonwick and Jonathan Adams, "Magazines and Vmem: Extending the Slab
     Allocator to Many CPUs and Arbitrary Resources", 2001 USENIX Annual
     Technical Conference, 2001.

AUTHORS
     This implementation of vmem was written by YAMAMOTO Takashi.

BUGS
     vmem relies on malloc(9), pool(9), and RUN_ONCE(9), so it cannot be used
     as early during system bootstrap as extent(9).

     vmem has no way to pass align, phase, nocross, minaddr, or maxaddr
     constraints into the backing allocator allocfn, so even if VM_SLEEP is
     specified, vmem_alloc() and vmem_xalloc() may spuriously fail immediately
     with align, phase, or nocross, or sleep forever with minaddr or maxaddr.

NetBSD 10.99                   December 2, 2023                   NetBSD 10.99