svn commit: r351476 - in head/sys: security/mac vm

Doug Moore dougm at FreeBSD.org
Sun Aug 25 07:06:53 UTC 2019


Author: dougm
Date: Sun Aug 25 07:06:51 2019
New Revision: 351476
URL: https://svnweb.freebsd.org/changeset/base/351476

Log:
  vm_map_simplify_entry considers merging an entry with its two
  neighbors, and is used in a way so that if entries a and b cannot be
  merged, we consider them twice, first not-merging a with its successor
  b, and then not-merging b with its predecessor a. This change replaces
  vm_map_simplify_entry with vm_map_try_merge_entries, which compares
  two adjacent entries only, and uses it to avoid duplicated
  merge-checks.
  
  Tested by: pho
  Reviewed by: alc
  Approved by: markj (implicit)
  Differential Revision: https://reviews.freebsd.org/D20814

Modified:
  head/sys/security/mac/mac_process.c
  head/sys/vm/vm_map.c
  head/sys/vm/vm_map.h

Modified: head/sys/security/mac/mac_process.c
==============================================================================
--- head/sys/security/mac/mac_process.c	Sun Aug 25 06:22:13 2019	(r351475)
+++ head/sys/security/mac/mac_process.c	Sun Aug 25 07:06:51 2019	(r351476)
@@ -363,7 +363,7 @@ mac_proc_vm_revoke_recurse(struct thread *td, struct u
 			}
 			pmap_protect(map->pmap, vme->start, vme->end,
 			    vme->protection & ~revokeperms);
-			vm_map_simplify_entry(map, vme);
+			vm_map_try_merge_entries(map, vme->prev, vme);
 		}
 	}
 	vm_map_unlock(map);

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c	Sun Aug 25 06:22:13 2019	(r351475)
+++ head/sys/vm/vm_map.c	Sun Aug 25 07:06:51 2019	(r351476)
@@ -1554,7 +1554,7 @@ charged:
 				map->size += end - prev_entry->end;
 			vm_map_entry_resize(map, prev_entry,
 			    end - prev_entry->end);
-			vm_map_simplify_entry(map, prev_entry);
+			vm_map_try_merge_entries(map, prev_entry, prev_entry->next);
 			return (KERN_SUCCESS);
 		}
 
@@ -1614,7 +1614,8 @@ charged:
 	 * with the previous entry when object is NULL.  Here, we handle the
 	 * other cases, which are less common.
 	 */
-	vm_map_simplify_entry(map, new_entry);
+	vm_map_try_merge_entries(map, prev_entry, new_entry);
+	vm_map_try_merge_entries(map, new_entry, new_entry->next);
 
 	if ((cow & (MAP_PREFAULT | MAP_PREFAULT_PARTIAL)) != 0) {
 		vm_map_pmap_enter(map, start, prot, object, OFF_TO_IDX(offset),
@@ -2083,34 +2084,24 @@ vm_map_merged_neighbor_dispose(vm_map_t map, vm_map_en
 }
 
 /*
- *	vm_map_simplify_entry:
+ *	vm_map_try_merge_entries:
  *
- *	Simplify the given map entry by merging with either neighbor.  This
- *	routine also has the ability to merge with both neighbors.
+ *	Compare the given map entry to its predecessor, and merge its precessor
+ *	into it if possible.  The entry remains valid, and may be extended.
+ *	The predecessor may be deleted.
  *
  *	The map must be locked.
- *
- *	This routine guarantees that the passed entry remains valid (though
- *	possibly extended).  When merging, this routine may delete one or
- *	both neighbors.
  */
 void
-vm_map_simplify_entry(vm_map_t map, vm_map_entry_t entry)
+vm_map_try_merge_entries(vm_map_t map, vm_map_entry_t prev, vm_map_entry_t entry)
 {
-	vm_map_entry_t next, prev;
 
-	if ((entry->eflags & MAP_ENTRY_NOMERGE_MASK) != 0)
-		return;
-	prev = entry->prev;
-	if (vm_map_mergeable_neighbors(prev, entry)) {
+	VM_MAP_ASSERT_LOCKED(map);
+	if ((entry->eflags & MAP_ENTRY_NOMERGE_MASK) == 0 &&
+	    vm_map_mergeable_neighbors(prev, entry)) {
 		vm_map_entry_unlink(map, prev, UNLINK_MERGE_NEXT);
 		vm_map_merged_neighbor_dispose(map, prev);
 	}
-	next = entry->next;
-	if (vm_map_mergeable_neighbors(entry, next)) {
-		vm_map_entry_unlink(map, next, UNLINK_MERGE_PREV);
-		vm_map_merged_neighbor_dispose(map, next);
-	}
 }
 
 /*
@@ -2580,7 +2571,8 @@ again:
 	 * [Note that clipping is not necessary the second time.]
 	 */
 	for (current = entry; current->start < end;
-	    vm_map_simplify_entry(map, current), current = current->next) {
+	    vm_map_try_merge_entries(map, current->prev, current),
+	    current = current->next) {
 		if (rv != KERN_SUCCESS ||
 		    (current->eflags & MAP_ENTRY_GUARD) != 0)
 			continue;
@@ -2618,6 +2610,7 @@ again:
 #undef	MASK
 		}
 	}
+	vm_map_try_merge_entries(map, current->prev, current);
 	vm_map_unlock(map);
 	return (rv);
 }
@@ -2722,8 +2715,9 @@ vm_map_madvise(
 			default:
 				break;
 			}
-			vm_map_simplify_entry(map, current);
+			vm_map_try_merge_entries(map, current->prev, current);
 		}
+		vm_map_try_merge_entries(map, current->prev, current);
 		vm_map_unlock(map);
 	} else {
 		vm_pindex_t pstart, pend;
@@ -2837,9 +2831,10 @@ vm_map_inherit(vm_map_t map, vm_offset_t start, vm_off
 		if ((entry->eflags & MAP_ENTRY_GUARD) == 0 ||
 		    new_inheritance != VM_INHERIT_ZERO)
 			entry->inheritance = new_inheritance;
-		vm_map_simplify_entry(map, entry);
+		vm_map_try_merge_entries(map, entry->prev, entry);
 		entry = entry->next;
 	}
+	vm_map_try_merge_entries(map, entry->prev, entry);
 	vm_map_unlock(map);
 	return (KERN_SUCCESS);
 }
@@ -3016,8 +3011,9 @@ vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offs
 			entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP;
 			need_wakeup = true;
 		}
-		vm_map_simplify_entry(map, entry);
+		vm_map_try_merge_entries(map, entry->prev, entry);
 	}
+	vm_map_try_merge_entries(map, entry->prev, entry);
 	vm_map_unlock(map);
 	if (need_wakeup)
 		vm_map_wakeup(map);
@@ -3313,8 +3309,9 @@ done:
 			entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP;
 			need_wakeup = true;
 		}
-		vm_map_simplify_entry(map, entry);
+		vm_map_try_merge_entries(map, entry->prev, entry);
 	}
+	vm_map_try_merge_entries(map, entry->prev, entry);
 	if (need_wakeup)
 		vm_map_wakeup(map);
 	return (rv);
@@ -3952,8 +3949,8 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_c
 				    old_entry->object.vm_object);
 
 				/*
-				 * As in vm_map_simplify_entry(), the
-				 * vnode lock will not be acquired in
+				 * As in vm_map_merged_neighbor_dispose(),
+				 * the vnode lock will not be acquired in
 				 * this call to vm_object_deallocate().
 				 */
 				vm_object_deallocate(object);

Modified: head/sys/vm/vm_map.h
==============================================================================
--- head/sys/vm/vm_map.h	Sun Aug 25 06:22:13 2019	(r351475)
+++ head/sys/vm/vm_map.h	Sun Aug 25 07:06:51 2019	(r351476)
@@ -418,7 +418,8 @@ void vm_map_lookup_done (vm_map_t, vm_map_entry_t);
 boolean_t vm_map_lookup_entry (vm_map_t, vm_offset_t, vm_map_entry_t *);
 int vm_map_protect (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t);
 int vm_map_remove (vm_map_t, vm_offset_t, vm_offset_t);
-void vm_map_simplify_entry(vm_map_t map, vm_map_entry_t entry);
+void vm_map_try_merge_entries(vm_map_t map, vm_map_entry_t prev,
+    vm_map_entry_t entry);
 void vm_map_startup (void);
 int vm_map_submap (vm_map_t, vm_offset_t, vm_offset_t, vm_map_t);
 int vm_map_sync(vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t);


More information about the svn-src-head mailing list