svn commit: r354570 - head/sys/vm

Doug Moore dougm at FreeBSD.org
Sat Nov 9 17:08:28 UTC 2019


Author: dougm
Date: Sat Nov  9 17:08:27 2019
New Revision: 354570
URL: https://svnweb.freebsd.org/changeset/base/354570

Log:
  For vm_map, #defining DIAGNOSTIC to turn on full assertion-based
  consistency checking slows performance dramatically. This change
  reduces the number of assertions checked by completely walking the
  vm_map tree only when the write-lock is released, and only then if the
  number of modifications to the tree since the last walk exceeds the
  number of tree nodes.
  
  Reviewed by: alc, kib
  Tested by: pho
  Differential Revision: https://reviews.freebsd.org/D22163

Modified:
  head/sys/vm/vm_map.c
  head/sys/vm/vm_map.h

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c	Sat Nov  9 11:55:01 2019	(r354569)
+++ head/sys/vm/vm_map.c	Sat Nov  9 17:08:27 2019	(r354570)
@@ -596,10 +596,54 @@ vm_map_process_deferred(void)
 	}
 }
 
+#ifdef INVARIANTS
+static void
+_vm_map_assert_locked(vm_map_t map, const char *file, int line)
+{
+
+	if (map->system_map)
+		mtx_assert_(&map->system_mtx, MA_OWNED, file, line);
+	else
+		sx_assert_(&map->lock, SA_XLOCKED, file, line);
+}
+
+#define	VM_MAP_ASSERT_LOCKED(map) \
+    _vm_map_assert_locked(map, LOCK_FILE, LOCK_LINE)
+
+enum { VMMAP_CHECK_NONE, VMMAP_CHECK_UNLOCK, VMMAP_CHECK_ALL };
+#ifdef DIAGNOSTIC
+static int enable_vmmap_check = VMMAP_CHECK_UNLOCK;
+#else
+static int enable_vmmap_check = VMMAP_CHECK_NONE;
+#endif
+SYSCTL_INT(_debug, OID_AUTO, vmmap_check, CTLFLAG_RWTUN,
+    &enable_vmmap_check, 0, "Enable vm map consistency checking");
+
+static void _vm_map_assert_consistent(vm_map_t map, int check);
+
+#define VM_MAP_ASSERT_CONSISTENT(map) \
+    _vm_map_assert_consistent(map, VMMAP_CHECK_ALL)
+#ifdef DIAGNOSTIC
+#define VM_MAP_UNLOCK_CONSISTENT(map) do {				\
+	if (map->nupdates > map->nentries) {				\
+		_vm_map_assert_consistent(map, VMMAP_CHECK_UNLOCK);	\
+		map->nupdates = 0;					\
+	}								\
+} while (0)
+#else
+#define VM_MAP_UNLOCK_CONSISTENT(map)
+#endif
+#else
+#define	VM_MAP_ASSERT_LOCKED(map)
+#define VM_MAP_ASSERT_CONSISTENT(map)
+#define VM_MAP_UNLOCK_CONSISTENT(map)
+#endif /* INVARIANTS */
+
 void
 _vm_map_unlock(vm_map_t map, const char *file, int line)
 {
 
+	VM_MAP_UNLOCK_CONSISTENT(map);
 	if (map->system_map)
 		mtx_unlock_flags_(&map->system_mtx, 0, file, line);
 	else {
@@ -697,8 +741,10 @@ _vm_map_lock_downgrade(vm_map_t map, const char *file,
 
 	if (map->system_map) {
 		mtx_assert_(&map->system_mtx, MA_OWNED, file, line);
-	} else
+	} else {
+		VM_MAP_UNLOCK_CONSISTENT(map);
 		sx_downgrade_(&map->lock, file, line);
+	}
 }
 
 /*
@@ -717,37 +763,6 @@ vm_map_locked(vm_map_t map)
 		return (sx_xlocked(&map->lock));
 }
 
-#ifdef INVARIANTS
-static void
-_vm_map_assert_locked(vm_map_t map, const char *file, int line)
-{
-
-	if (map->system_map)
-		mtx_assert_(&map->system_mtx, MA_OWNED, file, line);
-	else
-		sx_assert_(&map->lock, SA_XLOCKED, file, line);
-}
-
-#define	VM_MAP_ASSERT_LOCKED(map) \
-    _vm_map_assert_locked(map, LOCK_FILE, LOCK_LINE)
-
-#ifdef DIAGNOSTIC
-static int enable_vmmap_check = 1;
-#else
-static int enable_vmmap_check = 0;
-#endif
-SYSCTL_INT(_debug, OID_AUTO, vmmap_check, CTLFLAG_RWTUN,
-    &enable_vmmap_check, 0, "Enable vm map consistency checking");
-
-static void _vm_map_assert_consistent(vm_map_t map);
-
-#define VM_MAP_ASSERT_CONSISTENT(map) \
-    _vm_map_assert_consistent(map)
-#else
-#define	VM_MAP_ASSERT_LOCKED(map)
-#define VM_MAP_ASSERT_CONSISTENT(map)
-#endif /* INVARIANTS */
-
 /*
  *	_vm_map_unlock_and_wait:
  *
@@ -766,6 +781,7 @@ int
 _vm_map_unlock_and_wait(vm_map_t map, int timo, const char *file, int line)
 {
 
+	VM_MAP_UNLOCK_CONSISTENT(map);
 	mtx_lock(&map_sleep_mtx);
 	if (map->system_map)
 		mtx_unlock_flags_(&map->system_mtx, 0, file, line);
@@ -874,6 +890,9 @@ _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t mi
 	map->timestamp = 0;
 	map->busy = 0;
 	map->anon_loc = 0;
+#ifdef DIAGNOSTIC
+	map->nupdates = 0;
+#endif
 }
 
 void
@@ -1132,6 +1151,9 @@ vm_map_splay_merge(vm_map_t map, vm_map_entry_t root,
 	}		
 	root->max_free = MAX(max_free_left, max_free_right);
 	map->root = root;
+#ifdef DIAGNOSTIC
+	++map->nupdates;
+#endif
 }
 
 /*
@@ -1330,8 +1352,10 @@ vm_map_lookup_entry(
 		 * on a temporary upgrade.
 		 */
 		cur = vm_map_splay(map, address);
-		if (!locked)
+		if (!locked) {
+			VM_MAP_UNLOCK_CONSISTENT(map);
 			sx_downgrade(&map->lock);
+		}
 
 		/*
 		 * If "address" is contained within a map entry, the new root
@@ -4786,12 +4810,12 @@ vm_map_pmap_KBI(vm_map_t map)
 
 #ifdef INVARIANTS
 static void
-_vm_map_assert_consistent(vm_map_t map)
+_vm_map_assert_consistent(vm_map_t map, int check)
 {
 	vm_map_entry_t entry, prev;
 	vm_size_t max_left, max_right;
 
-	if (!enable_vmmap_check)
+	if (enable_vmmap_check != check)
 		return;
 
 	prev = &map->header;

Modified: head/sys/vm/vm_map.h
==============================================================================
--- head/sys/vm/vm_map.h	Sat Nov  9 11:55:01 2019	(r354569)
+++ head/sys/vm/vm_map.h	Sat Nov  9 17:08:27 2019	(r354570)
@@ -207,6 +207,9 @@ struct vm_map {
 	pmap_t pmap;			/* (c) Physical map */
 	vm_offset_t anon_loc;
 	int busy;
+#ifdef DIAGNOSTIC
+	int nupdates;
+#endif
 };
 
 /*


More information about the svn-src-head mailing list