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);

Reply via email to