this is a broken out piece of the previous more memory diff, revised.
as before, the idea is to allow uvm_map_hint to optionally select some of 
the reserved heap space if we have run out of room in the normal mmap 
space.

changes are that i'm using a macro now, to avoid changing code all over 
the kernel.  that should make things easier to adapt if we make this code 
smarter.  no need to expose allocation policy guts all over the kernel.

the only consumer of the new hint is at the bottom of uvm_mmap, where if 
we failed, we'll give it one more chance.

i'd like some test reports, on various archs.  the effects of reaching 
into the heap should be minimal, given:
        1. nothing uses the heap anymore
        2. it only allocates there if all the rest is used up
but I've rarely seen a uvm diff that didn't do something weirder than 
promised.


Index: uvm_map.c
===================================================================
RCS file: /home/tedu/cvs/src/sys/uvm/uvm_map.c,v
retrieving revision 1.130
diff -u -r1.130 uvm_map.c
--- uvm_map.c   15 Dec 2010 04:59:52 -0000      1.130
+++ uvm_map.c   16 Dec 2010 02:36:15 -0000
@@ -1241,7 +1241,7 @@
  * creating a new mapping with "prot" protection.
  */
 vaddr_t
-uvm_map_hint(struct proc *p, vm_prot_t prot)
+uvm_map_hint1(struct proc *p, vm_prot_t prot, int skipheap)
 {
        vaddr_t addr;
 
@@ -1258,7 +1258,9 @@
        }
 #endif
        /* start malloc/mmap after the brk */
-       addr = (vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ;
+       addr = (vaddr_t)p->p_vmspace->vm_daddr;
+       if (skipheap)
+               addr += BRKSIZ;
 #if !defined(__vax__)
        addr += arc4random() & (MIN((256 * 1024 * 1024), BRKSIZ) - 1);
 #endif
Index: uvm_map.h
===================================================================
RCS file: /home/tedu/cvs/src/sys/uvm/uvm_map.h,v
retrieving revision 1.43
diff -u -r1.43 uvm_map.h
--- uvm_map.h   20 Apr 2010 22:05:44 -0000      1.43
+++ uvm_map.h   16 Dec 2010 02:34:08 -0000
@@ -287,7 +287,8 @@
 vm_map_entry_t uvm_map_findspace(vm_map_t, vaddr_t, vsize_t, vaddr_t *,
                    struct uvm_object *, voff_t, vsize_t, int);
 vaddr_t                uvm_map_pie(vaddr_t);
-vaddr_t                uvm_map_hint(struct proc *, vm_prot_t);
+#define                uvm_map_hint(p, prot) uvm_map_hint1(p, prot, 1)
+vaddr_t                uvm_map_hint1(struct proc *, vm_prot_t, int);
 int            uvm_map_inherit(vm_map_t, vaddr_t, vaddr_t, vm_inherit_t);
 int            uvm_map_advice(vm_map_t, vaddr_t, vaddr_t, int);
 void           uvm_map_init(void);
Index: uvm_mmap.c
===================================================================
RCS file: /home/tedu/cvs/src/sys/uvm/uvm_mmap.c,v
retrieving revision 1.81
diff -u -r1.81 uvm_mmap.c
--- uvm_mmap.c  15 Dec 2010 04:59:53 -0000      1.81
+++ uvm_mmap.c  16 Dec 2010 02:44:37 -0000
@@ -604,6 +604,13 @@
 
        error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
            flags, handle, pos, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur, p);
+       if (error == ENOMEM && !(flags & (MAP_FIXED | MAP_TRYFIXED))) {
+               /* once more, with feeling */
+               addr = uvm_map_hint1(p, prot, 0);
+               error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size, prot,
+                   maxprot, flags, handle, pos,
+                   p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur, p);
+       }
 
        if (error == 0)
                /* remember to add offset */

Reply via email to