MMotor OS
System

Memory

Motor OS uses 4 KiB pages, eager mappings by default, and guarded lazy stacks. Instead of an OOM killer it has admission control: a memory-growing operation is refused before it starts if it would push the machine below a safety floor, and a shared "memory pressure" flag lets sys-io shed load before it runs out.

Pages and mappings

The heap allocator in every process is frusa, a small no-std allocator written for Motor OS that can grow and give memory back on demand.

Why admission control

Allocating N pages of data also costs page descriptors, page tables, and occasionally a new slab for kernel bookkeeping, about 2–2.5% on top of the data in measurements. Before admission control the kernel's low-memory check counted only the requested data pages and was separate from the allocation, so concurrent requests could all pass it, and one unprivileged process could empty the physical page pool and panic the kernel. Admission control is a stability mechanism, not a fairness policy: it does not pick a victim, does not promise that every lazy page will get backing, and does not attribute shared kernel objects to processes.

Floors

Two compile-time low-water marks over free small pages divide memory into zones:

available above USER_FLOOR (256 pages, 1 MiB):
    any process may start a memory-growing operation

SYS_IO_FLOOR (128 pages, 512 KiB) < available <= USER_FLOOR:
    only sys-io may

available <= SYS_IO_FLOOR:
    nobody may; what is left is for kernel work already in flight

The floors are constants, not configuration: an operator must not be able to configure the machine back into physical exhaustion. If measurements ever show they are too small, the floors are raised rather than a new allocation class added.

How an operation is admitted

Every userspace operation that grows memory (eager, lazy, shared, and contiguous mappings, page faults on lazy memory, stacks, address-space, process, and thread creation, kernel objects, IPC) is charged a conservative worst case, and a reservation for that charge is published in a global counter before the operation runs:

charge  = data_pages + ceil((data_pages + descriptors) / 32) + 64
admit iff (available - reservations) - charge >= floor

The reservation is held until the operation completes, which double-counts pages the operation has already allocated; that can refuse a request slightly early but can never admit too much. Fixed charges: a process 256 pages, a thread 64, a kernel object or IPC 16. A remote operation (sys-io loading a program into a new process) is charged against the target process's class, so a privileged loader does not widen an ordinary process's allowance.

What a refusal means:

Admission costs nothing measurable: in a release A/B test, eager 16-page allocate-and-free and warm lazy faults were within noise of the pre-admission build, and boot time was unchanged.

Pressure mode

The floors alone cannot keep sys-io alive, because sys-io's heap grows through the same allocator and a failed allocation aborts the process. Pressure mode stops sys-io's demand before the kernel has to refuse it. The kernel maintains a memory_pressure flag in a read-only page mapped into every process, with hysteresis so a single allocation or free cannot flip service on and off:

raise when free-for-admission <= 512 pages (2 MiB)
clear when free-for-admission >= 768 pages (3 MiB)

Any process can read the flag with one memory load. While it is up:

Nothing that must run during an episode may allocate; the refusal paths are allocation-free by construction. Established TCP connections keep working, because serving them allocates nothing. The flag clears from the page-free path as well, so it drops when the process that caused the pressure exits even if nobody else allocates.

Observability

Kernel metrics: mem.admission_refused_user, mem.admission_refused_sys_io, mem.admission_reserved_pages, mem.small_pages_low_water, mem.phys_small_pages_low_water, and the two floor gauges. sys-io metrics: net.pressure_active, net.pressure_entries, net.pressure_refused, net.pressure_refused_clients, net.pressure_deferred_replenish, fs.pressure_refused, and fs.pressure_refused_clients. A single syscall (F_QUERY_ADMISSION_STATS) reports availability, reservations, floors, and watermarks in one call. See Logs and diagnostics for how to read metrics.

Deliberately not built

The full argument, including the measurements that validated the floors, is in docs/oom-handling.md in the repository.