CONTIGMALLOC(9)

πŸ“¦
version 15.1 Β· 2 versions
, in freebsd 15.1, nixpkgs unstable

πŸŽ€ CONTIGMALLOC β€” the kernel developer's manual, bestie edition πŸŽ€

okay so this is CONTIGMALLOC(9), straight out of the Kernel Developer's Manual. yes it's section 9, yes that means kernel-stuff-only, no you cannot use it in your lil userland program. sit down, we're learning πŸ’…


✨ NAME ✨

contigmalloc β€” the way we manage contiguous kernel physical memory, and honestly? iconic. it gets you a chunk of physical memory where all the bytes are literally next to each other, no cap.


🌸 SYNOPSIS 🌸

first you gotta bring in the headers, like accessories:

#include <sys/types.h>
#include <sys/malloc.h>

then the main character:

void *
contigmalloc(unsigned long size, struct malloc_type *type, int flags,
    vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
    vm_paddr_t boundary);

and there's a whole second flavor, so grab these headers instead (or also, we don't judge):

#include <sys/param.h>
#include <sys/domainset.h>
void *
contigmalloc_domainset(unsigned long size, struct malloc_type *type,
    struct domainset *ds, int flags, vm_paddr_t low, vm_paddr_t high,
    unsigned long alignment, vm_paddr_t boundary);

πŸ¦‹ DESCRIPTION πŸ¦‹

so contigmalloc() allocates size bytes of contiguous physical memory, k? and it's all:

  • aligned to alignment bytes ⭐
  • and does not cross a boundary of boundary bytes 🚧

if it works out, your allocation lives between physical addresses low and high. and the pointer it hands back? that points to a wired kernel virtual address range of size bytes, allocated out of the kernel virtual address (KVA) map. wired means it's pinned down, it's not going anywhere, main character energy fr fr πŸ‘‘

the contigmalloc_domainset() variant is the same situation but it ALSO lets you specify a numa(4) domain selection policy. cute! see domainset(9) for some example policies if you want inspo 🫢

the flags parameter tweaks how contigmalloc() behaves, and here's the tea:

  • M_ZERO β€” causes the allocated physical memory to be zero filled. clean slate, fresh start, we love a blank canvas ✨
  • M_NOWAIT β€” causes contigmalloc() to return NULL if the request cannot be immediately fulfilled due to resource shortage. like, she's not gonna wait around πŸ’€

other flags (if present) are ignored. they're just there, vibing. πŸ™ˆ

okay important one: the contigfree() function is deprecated. use free(9) instead. like, it's giving outdated. moving on πŸ’…

🌈 IMPLEMENTATION NOTES 🌈

this is the part where you learn the lore 🧚

contigmalloc() does not sleep waiting for memory resources to be freed up. instead it actively reclaims pages before giving up β€” she's proactive, she's a go-getter, she goes and gets it πŸ”₯

BUT. unless M_NOWAIT is specified, it may select a page for reclamation that must first be written to backing storage, which causes it to sleep. 😭 so like, mostly not sleeping, but possibly sleeping. the plot thickens.


πŸ’œ RETURN VALUES πŸ’œ

  • contigmalloc() returns a kernel virtual address if allocation succeeds πŸŽ‰
  • or NULL otherwise 🫠

that's it. that's the return. binary. yes or no. slay or don't slay.


πŸ“ EXAMPLES πŸ“

void *p;
p = contigmalloc(8192, M_DEVBUF, M_ZERO, 0, (1L << 22),
    32 * 1024, 1024 * 1024);

so what is she actually asking for here, bestie? let me translate:

ask for 8192 bytes of zero-filled memory residing between physical address 0 and 4194303 inclusive, aligned to a 32K boundary and not crossing a 1M address boundary. periodt. πŸ’…


⭐ DIAGNOSTICS ⭐

contigmalloc() will panic if:

  • size is zero 🚨
  • or alignment or boundary is not a power of two 🚨

like genuinely panic. not a cute little error return. a whole panic. so double-check those powers of two before you ship, iykyk 😭


πŸ‘‘ SEE ALSO πŸ‘‘


okay that's the whole page, you ate that πŸ«ΆπŸ’–

this iconic lil number came from Debian, dated July 26, 2024 β€” go off, Debian, we love you for it πŸŒΈβœ¨πŸŽ€

πŸ“¦ where this page comes from