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
This commit is contained in:
dougm 2019-11-09 17:08:27 +00:00
parent b740365e0f
commit 63c1432c42
2 changed files with 62 additions and 35 deletions

View File

@ -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, int line)
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 min, vm_offset_t max)
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;

View File

@ -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
};
/*