svn commit: r258367 - head/sys/vm

Konstantin Belousov kib at FreeBSD.org
Wed Nov 20 09:03:49 UTC 2013


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


More information about the svn-src-head mailing list