Author: jhb
Date: Fri Jul 19 19:06:15 2013
New Revision: 253471
URL: http://svnweb.freebsd.org/changeset/base/253471

Log:
  Be more aggressive in using superpages in all mappings of objects:
  - Add a new address space allocation method (VMFS_OPTIMAL_SPACE) for
    vm_map_find() that will try to alter the alignment of a mapping to match
    any existing superpage mappings of the object being mapped.  If no
    suitable address range is found with the necessary alignment,
    vm_map_find() will fall back to using the simple first-fit strategy
    (VMFS_ANY_SPACE).
  - Change mmap() without MAP_FIXED, shmat(), and the GEM mapping ioctl to
    use VMFS_OPTIMAL_SPACE instead of VMFS_ANY_SPACE.
  
  Reviewed by:  alc (earlier version)
  MFC after:    2 weeks

Modified:
  head/sys/dev/drm2/i915/i915_gem.c
  head/sys/kern/sysv_shm.c
  head/sys/vm/vm_map.c
  head/sys/vm/vm_map.h
  head/sys/vm/vm_mmap.c

Modified: head/sys/dev/drm2/i915/i915_gem.c
==============================================================================
--- head/sys/dev/drm2/i915/i915_gem.c   Fri Jul 19 12:43:20 2013        
(r253470)
+++ head/sys/dev/drm2/i915/i915_gem.c   Fri Jul 19 19:06:15 2013        
(r253471)
@@ -1289,7 +1289,7 @@ i915_gem_mmap_ioctl(struct drm_device *d
        vm_object_reference(obj->vm_obj);
        DRM_UNLOCK(dev);
        rv = vm_map_find(map, obj->vm_obj, args->offset, &addr, args->size,
-           VMFS_ANY_SPACE, VM_PROT_READ | VM_PROT_WRITE,
+           VMFS_OPTIMAL_SPACE, VM_PROT_READ | VM_PROT_WRITE,
            VM_PROT_READ | VM_PROT_WRITE, MAP_SHARED);
        if (rv != KERN_SUCCESS) {
                vm_object_deallocate(obj->vm_obj);

Modified: head/sys/kern/sysv_shm.c
==============================================================================
--- head/sys/kern/sysv_shm.c    Fri Jul 19 12:43:20 2013        (r253470)
+++ head/sys/kern/sysv_shm.c    Fri Jul 19 19:06:15 2013        (r253471)
@@ -414,7 +414,7 @@ kern_shmat(td, shmid, shmaddr, shmflg)
        vm_object_reference(shmseg->object);
        rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object,
            0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE :
-           VMFS_ANY_SPACE, prot, prot, MAP_INHERIT_SHARE);
+           VMFS_OPTIMAL_SPACE, prot, prot, MAP_INHERIT_SHARE);
        if (rv != KERN_SUCCESS) {
                vm_object_deallocate(shmseg->object);
                error = ENOMEM;

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c        Fri Jul 19 12:43:20 2013        (r253470)
+++ head/sys/vm/vm_map.c        Fri Jul 19 19:06:15 2013        (r253471)
@@ -1444,19 +1444,29 @@ vm_map_find(vm_map_t map, vm_object_t ob
            vm_size_t length, int find_space, vm_prot_t prot,
            vm_prot_t max, int cow)
 {
-       vm_offset_t start;
+       vm_offset_t start, initial_addr;
        int result;
 
-       start = *addr;
+       if (find_space == VMFS_OPTIMAL_SPACE && (object == NULL ||
+           (object->flags & OBJ_COLORED) == 0))
+                       find_space = VMFS_ANY_SPACE;
+       initial_addr = *addr;
+again:
+       start = initial_addr;
        vm_map_lock(map);
        do {
                if (find_space != VMFS_NO_SPACE) {
                        if (vm_map_findspace(map, start, length, addr)) {
                                vm_map_unlock(map);
+                               if (find_space == VMFS_OPTIMAL_SPACE) {
+                                       find_space = VMFS_ANY_SPACE;
+                                       goto again;
+                               }
                                return (KERN_NO_SPACE);
                        }
                        switch (find_space) {
                        case VMFS_ALIGNED_SPACE:
+                       case VMFS_OPTIMAL_SPACE:
                                pmap_align_superpage(object, offset, addr,
                                    length);
                                break;
@@ -1473,11 +1483,11 @@ vm_map_find(vm_map_t map, vm_object_t ob
                }
                result = vm_map_insert(map, object, offset, start, start +
                    length, prot, max, cow);
-       } while (result == KERN_NO_SPACE && (find_space == VMFS_ALIGNED_SPACE
+       } while (result == KERN_NO_SPACE && (find_space == VMFS_ALIGNED_SPACE ||
 #ifdef VMFS_TLB_ALIGNED_SPACE
-           || find_space == VMFS_TLB_ALIGNED_SPACE
+           find_space == VMFS_TLB_ALIGNED_SPACE ||
 #endif
-           ));
+           find_space == VMFS_OPTIMAL_SPACE));
        vm_map_unlock(map);
        return (result);
 }

Modified: head/sys/vm/vm_map.h
==============================================================================
--- head/sys/vm/vm_map.h        Fri Jul 19 12:43:20 2013        (r253470)
+++ head/sys/vm/vm_map.h        Fri Jul 19 19:06:15 2013        (r253471)
@@ -343,9 +343,10 @@ long vmspace_resident_count(struct vmspa
  */
 #define        VMFS_NO_SPACE           0       /* don't find; use the given 
range */
 #define        VMFS_ANY_SPACE          1       /* find a range with any 
alignment */
-#define        VMFS_ALIGNED_SPACE      2       /* find a superpage-aligned 
range */
+#define        VMFS_OPTIMAL_SPACE      2       /* find a range with optimal 
alignment*/
+#define        VMFS_ALIGNED_SPACE      3       /* find a superpage-aligned 
range */
 #if defined(__mips__)
-#define        VMFS_TLB_ALIGNED_SPACE  3       /* find a TLB entry aligned 
range */
+#define        VMFS_TLB_ALIGNED_SPACE  4       /* find a TLB entry aligned 
range */
 #endif
 
 /*

Modified: head/sys/vm/vm_mmap.c
==============================================================================
--- head/sys/vm/vm_mmap.c       Fri Jul 19 12:43:20 2013        (r253470)
+++ head/sys/vm/vm_mmap.c       Fri Jul 19 19:06:15 2013        (r253471)
@@ -1603,7 +1603,8 @@ vm_mmap(vm_map_t map, vm_offset_t *addr,
        else if (fitit)
                rv = vm_map_find(map, object, foff, addr, size,
                    object != NULL && object->type == OBJT_DEVICE ?
-                   VMFS_ALIGNED_SPACE : VMFS_ANY_SPACE, prot, maxprot, docow);
+                   VMFS_ALIGNED_SPACE : VMFS_OPTIMAL_SPACE, prot, maxprot,
+                   docow);
        else
                rv = vm_map_fixed(map, object, foff, *addr, size,
                                 prot, maxprot, docow);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to