When sbrk() allocates a range of virtual memory, it immediately allocates a vm_amap and an am_slots array inside the amap There's one slot per page allocated, and a slot is 16 bytes in size (on 64 bit CPUs, 12 on 32 bit CPUs).
Preallocating slots makes sense mostly when we know that the memory range is going to be populated by physical pages. However, when doing sbrk(), physical pages are only allocated when actually accessing the range allocated. Why should we pre-allocate amap slots? Removing the UVM_FLAG_OVERLAY flag turns this into lazy slot allocation in chunks of 16 slots. The diff below reduce kmem pressure (and hangs because of it) especially in combination with the amap pool diff here: https://marc.info/?l=openbsd-tech&m=145763420910948&w=2 Tests that make sure that things don't break with this are welcome. Index: uvm/uvm_unix.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_unix.c,v retrieving revision 1.56 diff -u -p -r1.56 uvm_unix.c --- uvm/uvm_unix.c 5 May 2015 02:13:46 -0000 1.56 +++ uvm/uvm_unix.c 12 Mar 2016 10:24:24 -0000 @@ -87,7 +87,7 @@ sys_obreak(struct proc *p, void *v, regi UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_INHERIT_COPY, MADV_NORMAL, UVM_FLAG_AMAPPAD|UVM_FLAG_FIXED| - UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)); + UVM_FLAG_COPYONW)); if (error) { uprintf("sbrk: grow %ld failed, error = %d\n", new - old, error);