VMEM(9)

πŸ“¦
version 15.1 Β· 3 versions
, in freebsd 15.1

πŸ’– VMEM(9) β€” the kernel dev manual, bestie edition πŸ’–

okay so you're reading the VMEM(9) page, which is the Kernel Developer's Manual entry for vmem, and honestly? this one's a bop. let's get into it 🫢


✨ NAME ✨

vmem β€” the general purpose resource allocator, aka the friend who can hold anything for you πŸ’…


🌸 SYNOPSIS 🌸

#include <sys/vmem.h>

vmem_t *
vmem_create(const char *name, vmem_addr_t base, vmem_size_t size,
    vmem_size_t quantum, vmem_size_t qcache_max, int flags);

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

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

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

int
vmem_alloc(vmem_t *vm, vmem_size_t size, int 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 πŸ¦‹

so vmem is a general purpose resource allocator. and like β€” despite the name, it's not just for virtual memory. it can do arbitrary resources. it's giving versatility, it's giving main character energy ✨

πŸŽ€ vmem_create()

creates a new vmem arena. slay. here's the tea on the args:

  • name β€” the string that describes the vmem. its whole identity, honestly.
  • base β€” the start address of the initial span. pass 0 if you don't need an initial span, no pressure.
  • size β€” the size of the initial span. pass 0 if no initial span is required.
  • quantum β€” the smallest unit of allocation. tiny but mighty.
  • qcache_max β€” the largest size of allocations that can be served by the quantum cache. heads up: it's merely a hint and can be ignored. lowkey optional, fr.
  • flags β€” the malloc(9) wait flag.

🧚 vmem_add()

adds a span of size size starting at addr to the arena. returns 0 on success, ENOMEM on failure. and flags? that's the malloc(9) wait flag. πŸ’œ

πŸ”₯ vmem_xalloc()

allocates a resource from the arena. this is the fancy one, buckle up:

  • vm β€” the arena 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 description of align right above πŸ‘† if align is zero, phase should be zero. otherwise, phase should be smaller than align.
  • nocross β€” request a resource that doesn't cross a nocross aligned boundary.
  • minaddr β€” specify the minimum address that can be allocated, or VMEM_ADDR_MIN if the caller does not care.
  • maxaddr β€” specify the maximum address that can be allocated, or VMEM_ADDR_MAX if the caller does not care.
  • flags β€” a bitwise OR of an allocation strategy and a malloc(9) wait flag. the allocation strategy is one of these three icons:
    • M_FIRSTFIT β€” prefer allocation performance.
    • M_BESTFIT β€” prefer space efficiency.
    • M_NEXTFIT β€” perform an address-ordered search for free addresses, beginning where the previous search ended.
  • addrp β€” on success, if addrp is not NULL, vmem_xalloc() overwrites it with the start address of the allocated span.

πŸ’€ vmem_xfree()

frees a resource allocated by vmem_xalloc() back to the arena.

  • vm β€” the arena we free to.
  • addr β€” the resource being freed. it must be the one returned by vmem_xalloc(). and notably, it must not be the one from vmem_alloc(). otherwise the behaviour is undefined. 🚨 no mixing, bestie, i'm serious.
  • size β€” the size of the resource being freed. it must be the same as the size argument used for vmem_xalloc().

πŸ“ vmem_alloc()

allocates a resource from the arena. the chill everyday version:

  • vm β€” the arena we allocate from.
  • size β€” specify the size of the allocation.
  • flags β€” a bitwise OR of a vmem allocation strategy flag (see above πŸ‘€) and a malloc(9) sleep flag.
  • addrp β€” on success, if addrp is not NULL, vmem_alloc() overwrites it with the start address of the allocated span.

🌈 vmem_free()

frees a resource allocated by vmem_alloc() back to the arena.

  • vm β€” the arena we free to.
  • addr β€” the resource being freed. it must be the one returned by vmem_alloc(). notably, it must not be the one from vmem_xalloc(). otherwise, the behaviour is undefined. 😭 same rule, opposite direction, don't do it.
  • 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. RIP era.

  • vm β€” the vmem arena being destroyed. the caller should ensure that no one will use it anymore. like, nobody. not even a little. πŸ™ˆ

⭐ RETURN VALUES ⭐

vmem_create() returns a pointer to the newly allocated vmem_t. otherwise, it returns NULL. πŸ˜”

on success, vmem_xalloc() and vmem_alloc() return 0. otherwise, ENOMEM is returned. that's the whole story, ngl.


🧚 CODE REFERENCES 🧚

the vmem subsystem is implemented within the file sys/kern/subr_vmem.c. that's where the magic lives, iykyk πŸ’«


πŸŽ€ SEE ALSO πŸŽ€

  • malloc(9)
  • libuvmem(3) β€” for the userspace port of the allocator. yes, there's a userspace version, we love a spin-off 🫢
  • Jeff Bonwick and Jonathan Adams, β€œMagazines and Vmem: Extending the Slab Allocator to Many CPUs and Arbitrary Resources”, 2001 USENIX Annual Technical Conference, 2001. iconic academic behavior, honestly πŸ“š

🌸 HISTORY 🌸

the vmem allocator was originally implemented in NetBSD. it was introduced in FreeBSD 10.0. glow-up journey fr fr ✨


πŸ’œ AUTHORS πŸ’œ

original implementation of vmem was written by YAMAMOTO Takashi. the FreeBSD port was made by Jeff Roberson. legends, both of them πŸ‘‘


πŸ’… BUGS πŸ’…

vmem relies on malloc(9), so it cannot be used as early during system bootstrap. that's the one limitation, and it's real β€” plan around it, bestie.


okay that's the whole page, you ate that πŸ’– go allocate something responsibly πŸ¦‹

Debian Β· May 17, 2019 Β· that's the source, the date, and the version, all wrapped up with a bow πŸŽ€ mwah πŸ’‹

πŸ“¦ where this page comes from