MALLOC(9)

NAME
malloc, mallocarray, free - kernel memory allocator

SYNOPSIS
#include <sys/types.h>
#include <sys/malloc.h>
void *
malloc(size_t size, int type, int flags);
void *
mallocarray(size_t nmemb, size_t size, int type, int flags);
void
free(void *addr, int type, size_t size);

DESCRIPTION
The malloc() function allocates uninitialized memory in kernel address space for an object whose size is specified by size.

The mallocarray() function is the same as malloc(), but allocates space for an array of nmemb objects and checks for arithmetic overflow.

The free() function releases memory at address addr that was previously allocated by malloc() or mallocarray() for re-use. The same object size originally provided to malloc() should be specified by size, because free() will operate faster knowing this. If tracking the size is difficult, specify size as 0. If addr is a null pointer, no action occurs.

The flags argument affects the operational characteristics of malloc() and mallocarray() as follows:

M_WAITOK
    If memory is currently unavailable, malloc() may call sleep to wait for resources to be released by other processes.

M_NOWAIT
    Causes malloc() to return NULL if the request cannot be immediately fulfilled due to resource shortage.

M_CANFAIL
    In the M_WAITOK case, if not enough memory is available, return NULL instead of calling panic(9). If mallocarray() detects an overflow or malloc() detects an excessive allocation, return NULL instead of calling panic(9).

M_ZERO
    Causes allocated memory to be zeroed.

One of M_NOWAIT or M_WAITOK must be specified via the flags argument.

The type argument broadly identifies the kernel subsystem for which the allocated memory was needed, and is commonly used to maintain statistics about kernel memory usage. These statistics can be examined using vmstat(8) or systat(1) if either of the kernel options(4) KMEMSTATS or DEBUG are enabled.

The following types are currently defined:

M_FREE
    Should be on free list.
M_DEVBUF
    Device driver memory.
M_DEBUG
    malloc debug structures.
M_PCB
    Protocol control blocks.
M_RTABLE
    Routing tables.
M_FTABLE
    Fragment reassembly headers.
M_IFADDR
    Interface addresses.
M_SOOPTS
    Socket options.
M_SYSCTL
    Sysctl persistent buffers.
M_COUNTERS
    Per-CPU Counters for use via counters_alloc(9).
M_IOCTLOPS
    Ioctl data buffers.
M_IOV
    Large IOVs.
M_MOUNT
    VFS mount structs.
M_NFSREQ
    NFS request headers.
M_NFSMNT
    NFS mount structures.
M_VNODE
    Dynamically allocated vnodes.
M_CACHE
    Dynamically allocated cache entries.
M_DQUOT
    UFS quota entries.
M_UFSMNT
    UFS mount structures.
M_SHM
    SVID compatible shared memory segments.
M_VMMAP
    VM map structures.
M_SEM
    SVID compatible semaphores.
M_DIRHASH
    UFS directory hash structures.
M_ACPI
    ACPI structures.
M_VMPMAP
    VM pmap data.
M_FILE
    Open file structures.
M_FILEDESC
    Open file descriptor tables.
M_PROC
    Proc structures.
M_SUBPROC
    Proc sub-structures.
M_VCLUSTER
    Cluster for VFS.
M_MFSNODE
    MFS vnode private part.
M_NETADDR
    Export host address structures.
M_NFSSVC
    NFS server structures.
M_NFSD
    NFS server daemon structures.
M_IPMOPTS
    Internet multicast options.
M_IPMADDR
    Internet multicast addresses.
M_IFMADDR
    Link-level multicast addresses.
M_MRTABLE
    Multicast routing tables.
M_ISOFSMNT
    ISOFS mount structures.
M_ISOFSNODE
    ISOFS vnode private part.
M_MSDOSFSMNT
    MSDOS FS mount structures.
M_MSDOSFSFAT
    MSDOS FS FAT tables.
M_MSDOSFSNODE
    MSDOS FS vnode private part.
M_TTYS
    Allocated tty structures.
M_EXEC
    Argument lists & other mem used by exec.
M_MISCFSMNT
    Miscellaneous FS mount structures.
M_FUSEFS
    FUSE FS mount structures.
M_PFKEY
    Pfkey data.
M_TDB
    Transforms database.
M_XDATA
    IPsec data.
M_PAGEDEP
    File page dependencies.
M_INODEDEP
    Inode dependencies.
M_NEWBLK
    New block allocation.
M_INDIRDEP
    Indirect block dependencies.
M_VMSWAP
    VM swap structures.
M_UVMAMAP
    UVM amap and related.
M_UVMAOBJ
    UVM aobj and related.
M_USB
    USB general.
M_USBDEV
    USB device driver.
M_USBHC
    USB host controller.
M_MEMDESC
    Memory range.
M_CRYPTO_DATA
    crypto(9) data buffers.
M_CREDENTIALS
    ipsec(4) related credentials.
M_EMULDATA
    Per process emulation data.
M_IP6OPT
    IPv6 options.
M_IP6NDP
    IPv6 neighbour discovery structures.
M_TEMP
    Miscellaneous temporary data buffers.
M_NTFSMNT
    NTFS mount structures.
M_NTFSNTNODE
    NTFS ntnode information.
M_NTFSNODE
    NTFS fnode information.
M_NTFSDIR
    NTFS directory buffers.
M_NTFSHASH
    NTFS ntnode hash tables.
M_NTFSVATTR
    NTFS file attribute information.
M_NTFSRDATA
    NTFS resident data.
M_NTFSDECOMP
    NTFS decompression temporary storage.
M_NTFSRUN
    NTFS vrun storage.
M_KEVENT
    kqueue(2) data structures.
M_UDFMOUNT
    UDF mount structures.
M_UDFFENTRY
    UDF file entries.
M_UDFFID
    UDF file ID.
M_AGP
    AGP memory.
M_DRM
    Direct Rendering Manager.

CONTEXT
malloc() and mallocarray() can be called during autoconf, from process context, or from interrupt context if M_NOWAIT is passed via flags. They can't be called from interrupt context if M_WAITOK is passed via flags.

free() can be called during autoconf, from process context, or from interrupt context.

RETURN VALUES
malloc() and mallocarray() return a kernel virtual address that is suitably aligned for storage of any type of object.

DIAGNOSTICS
A kernel compiled with the DIAGNOSTIC configuration option attempts to detect memory corruption caused by such things as writing outside the allocated area and unbalanced calls to malloc() or mallocarray(), and free(). Failing consistency checks will cause a panic or a system console message:

•   panic: “malloc: bogus type”
•   panic: “malloc: out of space in kmem_map”
•   panic: “malloc: allocation too large”
•   panic: “malloc: wrong bucket”
•   panic: “malloc: lost data”
•   panic: “mallocarray: overflow”
•   panic: “free: unaligned addr”
•   panic: “free: duplicated free”
•   panic: “free: multiple frees”
•   panic: “free: non-malloced addr”
•   panic: “free: size too large”
•   panic: “free: size too small”
•   panic: “kmeminit: minbucket too small/struct freelist too big”
•   “multiply freed item <addr>”
•   “Data modified on freelist: <data object description>”

DEBUGGING
A kernel compiled with the MALLOC_DEBUG option allows for more extensive debugging of memory allocations. The debug_malloc_type, debug_malloc_size, debug_malloc_size_lo and debug_malloc_size_hi variables choose which allocation to debug. debug_malloc_type should be set to the memory type and debug_malloc_size should be set to the memory size to debug. 0 can be used as a wildcard. debug_malloc_size_lo and debug_malloc_size_hi can be used to specify a range of sizes if the exact size to debug is not known. When those are used, debug_malloc_size needs to be set to the wildcard. M_DEBUG can also be specified as an allocation type to force allocation with debugging.

Every call to malloc() or mallocarray() with a memory type and size that matches the debugged type and size will allocate two virtual pages. The pointer returned will be aligned so that the requested area will end at the page boundary and the second virtual page will be left unmapped. This way we can catch reads and writes outside the allocated area.

Every call to free() with memory that was returned by the debugging allocators will cause the memory area to become unmapped so that we can catch dangling reads and writes to freed memory.

There are no special diagnostics if any errors are caught by the debugging malloc. The errors will look like normal access to unmapped memory. On a memory access error, the show malloc command in ddb(4) can be invoked to see what memory areas are allocated and freed. If the faulting address is within two pages from an address on the allocated list, there was an access outside the allocated area. If the faulting address is within two pages from an address on the free list, there was an access to freed memory.

Care needs to be taken when using the MALLOC_DEBUG option: the memory consumption can run away pretty quickly and there is a severe performance degradation when allocating and freeing debugged memory types.

SEE ALSO
systat(1), vmstat(8)