]> Zhao Yanbai Git Server - minix.git/commitdiff
vm: if mmap address is given, try that first
authorDavid van Moolenbroek <david@minix3.org>
Sun, 22 Jan 2012 17:20:45 +0000 (18:20 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Sat, 24 Mar 2012 18:51:14 +0000 (19:51 +0100)
Previously, the mmap address (if given) was merely used as a lower
bound, and then possibly overriden with a hint. Now, the mapping is
first tried at the exact given address. If that fails, the start of
the mmap range is used as lower bound (which is then still overridden
by the hint for efficiency).

This allows two pages to be mapped in at predefined addresses, where
the second address is lower than the first. That was not possible.

servers/vm/mmap.c

index 8e1c3abc4d9b9f1cd4c856b058d7ee5d1190db3b..a61fee08a0676e555b05145408b6fba2386912d3 100644 (file)
@@ -40,6 +40,7 @@ PUBLIC int do_mmap(message *m)
        int r, n;
        struct vmproc *vmp;
        int mfflags = 0;
+       vir_bytes addr;
        struct vir_region *vr = NULL;
 
        if((r=vm_isokendpt(m->m_source, &n)) != OK) {
@@ -81,10 +82,20 @@ PUBLIC int do_mmap(message *m)
                if(len % VM_PAGE_SIZE)
                        len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
 
-               if(!(vr = map_page_region(vmp,
-                       arch_vir2map(vmp,
-                               m->VMM_ADDR ? m->VMM_ADDR : vmp->vm_stacktop),
-                       VM_DATATOP, len, MAP_NONE, vrflags, mfflags))) {
+               vr = NULL;
+               if (m->VMM_ADDR) {
+                       /* An address is given, first try at that address. */
+                       addr = arch_vir2map(vmp, m->VMM_ADDR);
+                       vr = map_page_region(vmp, addr, 0, len, MAP_NONE,
+                               vrflags, mfflags);
+               }
+               if (!vr) {
+                       /* No address given or address already in use. */
+                       addr = arch_vir2map(vmp, vmp->vm_stacktop);
+                       vr = map_page_region(vmp, addr, VM_DATATOP, len,
+                               MAP_NONE, vrflags, mfflags);
+               }
+               if (!vr) {
                        return ENOMEM;
                }
        } else {