MLOCK(2)
๐ MLOCK(2) โ the "pin it down, bestie" page ๐
okay so this is the manual page for mlock, munlock from the System Calls Manual, and honestly? it's giving "I need these pages to STAY PUT" energy. let's get into it ๐ซถ
โจ NAME โจ
mlock, munlock โ lock (unlock) physical pages in memory ๐๐
๐ LIBRARY ๐
Standard C Library (libc, -lc)
๐ธ SYNOPSIS ๐ธ
#include <sys/mman.h>
int
mlock(const void *addr, size_t len);
int
munlock(const void *addr, size_t len);
๐ DESCRIPTION ๐
so the mlock() system call locks into memory the physical pages associated with the virtual address range starting at addr for len bytes. it's literally grabbing those pages and going "you're not going anywhere, babe." โ
and munlock()? it unlocks pages that were previously locked by one or more mlock() calls. the release, the letting go, the moving on ๐ฆ
for both of them, the addr argument should be aligned to a multiple of the page size. and if len isn't a multiple of the page size, bestie, it gets rounded up to be so. the entire range must be allocated โ no phantom pages, no cap. โจ
After an mlock() system call, the indicated pages will cause neither a non-resident page nor address-translation fault until they are unlocked. (iconic behaviour, honestly.) they may still cause protection-violation faults or TLB-miss faults on architectures with software-managed TLBs โ so like, mostly immune, not fully immune, iykyk ๐
the physical pages remain in memory until all locked mappings for the pages are removed. multiple processes may have the same physical pages locked via their own virtual address mappings. a single process may likewise have pages multiply-locked via different virtual mappings of the same physical pages. the way that one physical page can be living its main character life in like five different address spaces at once ๐ญ
Unlocking is performed explicitly by munlock() or implicitly by a call to munmap() which deallocates the unmapped address range. and locked mappings are not inherited by the child process after fork(2) โ sorry to that child, they get nothing ๐
โ ๏ธ scarcity alert โ ๏ธ Since physical memory is a potentially scarce resource, processes are limited in how much they can lock down.
The amount of memory that a single process can mlock() is limited by both:
- the per-process
RLIMIT_MEMLOCKresource limit, and - the system-wide "wired pages" limit
vm.max_user_wired.
and here's the tea: vm.max_user_wired applies to the system as a whole, so the amount available to a single process at any given time is the difference between vm.max_user_wired and vm.stats.vm.v_user_wire_count. math is math, bestie ๐งฎ
If security.bsd.unprivileged_mlock is set to 0 these calls are only available to the super-user. ๐ so like... know your power level before you try.
๐ RETURN VALUES ๐
Upon successful completion, the value 0 is returned; otherwise the value -1 is returned and the global variable errno is set to indicate the error.
If the call succeeds, all pages in the range become locked (unlocked); otherwise the locked status of all pages in the range remains unchanged. it's all-or-nothing, no partial credit, no half-sending the vibe ๐
๐ฅ ERRORS ๐ฅ
The mlock() system call will fail if:
[EPERM]โsecurity.bsd.unprivileged_mlockis set to0and the caller is not the super-user. (no key, no entry ๐ซ)[EINVAL]โ The address range given wraps around zero. (wrapping around zero is not the serve you think it is ๐)[ENOMEM]โ Some portion of the indicated address range is not allocated. There was an error faulting/mapping a page. Locking the indicated range would exceed the per-process or system-wide limits for locked memory.
The munlock() system call will fail if:
[EPERM]โsecurity.bsd.unprivileged_mlockis set to0and the caller is not the super-user.[EINVAL]โ The address range given wraps around zero.[ENOMEM]โ Some or all of the address range specified by theaddrandlenarguments does not correspond to valid mapped pages in the address space of the process.[ENOMEM]โ Locking the pages mapped by the specified range would exceed a limit on the amount of memory that the process may lock.
๐ฆ SEE ALSO ๐ฆ
fork(2), mincore(2), minherit(2), mlockall(2), mmap(2), munlockall(2), munmap(2), setrlimit(2), getpagesize(3)
(the whole friend group, fr fr ๐ซถ)
๐ HISTORY ๐
The mlock() and munlock() system calls first appeared in 4.4BSD. old money, vintage, classic ๐
๐ญ BUGS ๐ญ
- Allocating too much wired memory can lead to a memory-allocation deadlock which requires a reboot to recover from. ๐จ not a vibe. not the moment. be careful out there bestie.
- The per-process and system-wide resource limits of locked memory apply to the amount of virtual memory locked, not the amount of locked physical pages. Hence two distinct locked mappings of the same physical page counts as 2 pages aginst the system limit, and also against the per-process limit if both mappings belong to the same physical map. (yes, double-counted. the audacity ๐ค)
- The per-process resource limit is not currently supported.
and that's the whole page, bestie!! this one's from the Debian crew, dated May 13, 2019 โ so like, it's been serving this exact energy for a minute. lock your pages, respect the limits, and stay hydrated ๐โจ๐
๐ฆ where this page comes from
- debian bookworm: freebsd-manpages 12.2-1 ยท BSD-2-Clause-FreeBSD AND BSD-4-Clause
- debian trixie: freebsd-manpages 12.2-2 ยท BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu jammy: freebsd-manpages 12.2-1 ยท BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu noble: freebsd-manpages 12.2-1 ยท BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu questing: freebsd-manpages 12.2-2
- ubuntu resolute: freebsd-manpages 12.2-2build1 ยท BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu stonking: freebsd-manpages 12.2-2build1 ยท BSD-2-Clause-FreeBSD AND BSD-4-Clause
- Copyright (c) 1993 The Regents of the University of California. All rights reserved
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms