Author: kib
Date: Wed Nov 20 09:03:48 2013
New Revision: 258367
URL: http://svnweb.freebsd.org/changeset/base/258367

Log:
  Vm map code performs clipping when map entry covers region which is
  larger than the operational region.  If the op region size is zero,
  clipping would create a zero-sized map entry.  The result is that vm
  map splay starts behaving inconsistently, sometimes returning
  zero-sized entry, sometimes the next (or previous) entry.
  
  One step further, it could result in e.g. vm_map_wire() setting
  MAP_ENTRY_IN_TRANSITION on the zero-sized entry, but failing to clear
  it in the done part.  The vm_map_delete() than hangs forever waiting
  for the flag removal.
  
  Verify for zero-length requests and act as if it is always successfull
  without performing any action on the address space.
  
  Diagnosed by: pho
  Tested by:    pho (previous version)
  Reviewed by:  alc (previous version)
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week

Modified:
  head/sys/vm/vm_map.c

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c        Wed Nov 20 08:47:54 2013        (r258366)
+++ head/sys/vm/vm_map.c        Wed Nov 20 09:03:48 2013        (r258367)
@@ -1876,6 +1876,9 @@ vm_map_protect(vm_map_t map, vm_offset_t
        struct ucred *cred;
        vm_prot_t old_prot;
 
+       if (start == end)
+               return (KERN_SUCCESS);
+
        vm_map_lock(map);
 
        VM_MAP_RANGE_CHECK(map, start, end);
@@ -2030,12 +2033,16 @@ vm_map_madvise(
        case MADV_AUTOSYNC:
        case MADV_NOCORE:
        case MADV_CORE:
+               if (start == end)
+                       return (KERN_SUCCESS);
                modify_map = 1;
                vm_map_lock(map);
                break;
        case MADV_WILLNEED:
        case MADV_DONTNEED:
        case MADV_FREE:
+               if (start == end)
+                       return (KERN_SUCCESS);
                vm_map_lock_read(map);
                break;
        default:
@@ -2190,6 +2197,8 @@ vm_map_inherit(vm_map_t map, vm_offset_t
        default:
                return (KERN_INVALID_ARGUMENT);
        }
+       if (start == end)
+               return (KERN_SUCCESS);
        vm_map_lock(map);
        VM_MAP_RANGE_CHECK(map, start, end);
        if (vm_map_lookup_entry(map, start, &temp_entry)) {
@@ -2222,6 +2231,8 @@ vm_map_unwire(vm_map_t map, vm_offset_t 
        int rv;
        boolean_t need_wakeup, result, user_unwire;
 
+       if (start == end)
+               return (KERN_SUCCESS);
        user_unwire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
        vm_map_lock(map);
        VM_MAP_RANGE_CHECK(map, start, end);
@@ -2392,6 +2403,8 @@ vm_map_wire(vm_map_t map, vm_offset_t st
        boolean_t fictitious, need_wakeup, result, user_wire;
        vm_prot_t prot;
 
+       if (start == end)
+               return (KERN_SUCCESS);
        prot = 0;
        if (flags & VM_MAP_WIRE_WRITE)
                prot |= VM_PROT_WRITE;
@@ -2833,6 +2846,8 @@ vm_map_delete(vm_map_t map, vm_offset_t 
        vm_map_entry_t first_entry;
 
        VM_MAP_ASSERT_LOCKED(map);
+       if (start == end)
+               return (KERN_SUCCESS);
 
        /*
         * Find the start of the region, and clip it
_______________________________________________
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