macOS vm.user_wire_limit and RLIMIT_MEMLOCK for mlock
Parent: Mac local LLMs: Memory and wired limits · Published reference · snapshot 2026-10-05
↓ Facts as markdownall context files
Over-limit failure returns KERN_RESOURCE_SHORTAGE, which mlock maps to EAGAIN, not ENOMEM. Any other failure maps to ENOMEM.
These notes link each claim to its source. A source may be a research report hosted on this site rather than the primary document. A published reference means the content is available; it does not certify independent review or accuracy.Read the editorial policy and follow the sources before relying on a claim.
Facts
- Over-limit failure returns KERN_RESOURCE_SHORTAGE, which mlock maps to EAGAIN, not ENOMEM. Any other failure maps to ENOMEM. [source]
- llama.cpp prints its raise-the-limits hint only for ENOMEM (see existing dossier), so an over-limit mlock on macOS may fail without the hint. [source]
- mlockall and munlockall return ENOSYS on macOS. [source]
- munlock removes one wiring, not all (source comment "JMM - need to remove all wirings by spec"). [source]
- fork copies the parent's user_wire_limit into the child map. [source]
- On DEVELOPMENT or DEBUG kernels, a panic_on_mlock_failure switch can panic on an over-limit mlock; release kernels only increment counters. [source]
- Existing dossier: llama.cpp hint appears when mlock fails with ENOMEM. This source: the limit check yields EAGAIN. The two are not reconciled; a macOS run with strerror output would settle it. [source]
- Which file defines the vm.user_wire_limit, vm.global_user_wire_limit and vm.global_no_user_wire_amount sysctls and their Apple-silicon defaults (not found in bsd/vm/vm_unix.c as fetched). [source]
- Whether a Metal buffer made by newBufferWithBytesNoCopy over mlocked pages is counted once or twice in the system wired count. [source]
- XNU mlock(2) calls vm_map_wire_kernel(current_map(), addr, end, VM_PROT_NONE, VM_KERN_MEMORY_MLOCK, TRUE) with user_wire true. [source]
- mlock maps KERN_RESOURCE_SHORTAGE to EAGAIN, KERN_INVALID_ARGUMENT to EINVAL, KERN_PROTECTION_FAILURE to EPERM and every other failure to ENOMEM. [source]
- mlockall and munlockall return ENOSYS on macOS. [source]
- munlock calls vm_map_unwire once and carries a comment that the spec requires removing all wirings but it removes one. [source]
- The user wire check runs only when a map entry's user_wired_count is 0, i.e. the first time the user wires that entry. [source]
- The per-map cap is MIN(map->user_wire_limit, vm_per_task_user_wire_limit) compared against map->user_wire_size plus the request. [source]
- The system-wide cap compares the request plus ptoa_64(vm_page_wire_count + vm_lopage_free_count) against vm_global_user_wire_limit. [source]
- A failed limit check returns KERN_RESOURCE_SHORTAGE and increments vm_add_wire_count_over_global_limit or vm_add_wire_count_over_user_limit. [source]
- A new vm_map is created with user_wire_limit = MACH_VM_MAX_ADDRESS, commented "default limit is unlimited". [source]
- vm_map_fork copies user_wire_limit from the old map to the new map. [source]
- setrlimit for RLIMIT_MEMLOCK calls vm_map_set_user_wire_limit(current_map(), rlim_cur). [source]
- mach_vm_wire_level_monitor derives its page budget from vm_global_user_wire_limit minus vm_page_wire_count, so kernel wiring requests are throttled by the same global limit. [source]
- Because the per-process RLIMIT_MEMLOCK default is unlimited in the map, the effective per-process ceiling for mlock on a stock Mac is vm_per_task_user_wire_limit, not the shell's ulimit -l. [source]
- An over-limit llama.cpp --mlock on macOS likely reports EAGAIN ("Resource temporarily unavailable"), so the ENOMEM-gated hint would not print. [source]
Children
- No children recorded.