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. Some citations identify archived research reports that are no longer hosted on this site. 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.