Author: alc
Date: Mon Oct  4 16:49:40 2010
New Revision: 213408
URL: http://svn.freebsd.org/changeset/base/213408

Log:
  If vm_map_find() is asked to allocate a superpage-aligned region of virtual
  addresses that is greater than a superpage in size but not a multiple of
  the superpage size, then vm_map_find() is not always expanding the kernel
  pmap to support the last few small pages being allocated.  These failures
  are not commonplace, so this was first noticed by someone porting FreeBSD
  to a new architecture.  Previously, we grew the kernel page table in
  vm_map_findspace() when we found the first available virtual address.
  This works most of the time because we always grow the kernel pmap or page
  table by an amount that is a multiple of the superpage size.  Now, instead,
  we defer the call to pmap_growkernel() until we are committed to a range
  of virtual addresses in vm_map_insert().  In general, there is another
  reason to prefer calling pmap_growkernel() in vm_map_insert().  It makes
  it possible for someone to do the equivalent of an mmap(MAP_FIXED) on the
  kernel map.
  
  Reported by:  Svatopluk Kraus
  Reviewed by:  kib@
  MFC after:    3 weeks

Modified:
  head/sys/vm/vm_map.c

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c        Mon Oct  4 16:07:48 2010        (r213407)
+++ head/sys/vm/vm_map.c        Mon Oct  4 16:49:40 2010        (r213408)
@@ -1163,6 +1163,9 @@ vm_map_insert(vm_map_t map, vm_object_t 
        }
 
 charged:
+       /* Expand the kernel pmap, if necessary. */
+       if (map == kernel_map && end > kernel_vm_end)
+               pmap_growkernel(end);
        if (object != NULL) {
                /*
                 * OBJ_ONEMAPPING must be cleared unless this mapping
@@ -1299,7 +1302,7 @@ vm_map_findspace(vm_map_t map, vm_offset
     vm_offset_t *addr) /* OUT */
 {
        vm_map_entry_t entry;
-       vm_offset_t end, st;
+       vm_offset_t st;
 
        /*
         * Request must fit within min/max VM address and must avoid
@@ -1313,7 +1316,7 @@ vm_map_findspace(vm_map_t map, vm_offset
        /* Empty tree means wide open address space. */
        if (map->root == NULL) {
                *addr = start;
-               goto found;
+               return (0);
        }
 
        /*
@@ -1323,7 +1326,7 @@ vm_map_findspace(vm_map_t map, vm_offset
        map->root = vm_map_entry_splay(start, map->root);
        if (start + length <= map->root->start) {
                *addr = start;
-               goto found;
+               return (0);
        }
 
        /*
@@ -1334,7 +1337,7 @@ vm_map_findspace(vm_map_t map, vm_offset
        st = (start > map->root->end) ? start : map->root->end;
        if (length <= map->root->end + map->root->adj_free - st) {
                *addr = st;
-               goto found;
+               return (0);
        }
 
        /* With max_free, can immediately tell if no solution. */
@@ -1352,22 +1355,13 @@ vm_map_findspace(vm_map_t map, vm_offset
                        entry = entry->left;
                else if (entry->adj_free >= length) {
                        *addr = entry->end;
-                       goto found;
+                       return (0);
                } else
                        entry = entry->right;
        }
 
        /* Can't get here, so panic if we do. */
        panic("vm_map_findspace: max_free corrupt");
-
-found:
-       /* Expand the kernel pmap, if necessary. */
-       if (map == kernel_map) {
-               end = round_page(*addr + length);
-               if (end > kernel_vm_end)
-                       pmap_growkernel(end);
-       }
-       return (0);
 }
 
 int
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to