diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 4f4716e58faf..d868823d9bea 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -152,8 +152,8 @@ __FBSDID("$FreeBSD$"); * will hold LOCK_NCHILDREN locks. We handle failure ok, and we should * probably be safe for the most part, but it's still a SWAG. */ -#define LOCK_NCHILDREN 5 -#define LOCK_CHILDCOUNT 2048 +#define LOCK_NCHILDREN 20 +#define LOCK_CHILDCOUNT 4096 #define MAX_W_NAME 64 @@ -352,6 +352,7 @@ static struct witness *witness_hash_get(const char *key); static void witness_hash_put(struct witness *w); static void witness_init_hash_tables(void); static void witness_increment_graph_generation(void); +static void witness_init_lock_list(void); static void witness_lock_list_free(struct lock_list_entry *lle); static struct lock_list_entry *witness_lock_list_get(void); static int witness_lock_order_add(struct witness *parent, @@ -457,6 +458,12 @@ static struct witness_list w_spin = STAILQ_HEAD_INITIALIZER(w_spin); static struct witness_list w_sleep = STAILQ_HEAD_INITIALIZER(w_sleep); /* lock list */ +static u_int lock_list_used; +static u_int lock_list_max_used; + +SYSCTL_INT(_debug_witness, OID_AUTO, list_used, CTLFLAG_RD, &lock_list_used, 0, ""); +SYSCTL_INT(_debug_witness, OID_AUTO, list_max_used, CTLFLAG_RD, &lock_list_max_used, 0, ""); + static struct lock_list_entry *w_lock_list_free = NULL; static struct witness_pendhelp pending_locks[WITNESS_PENDLIST]; static u_int pending_cnt; @@ -796,8 +803,7 @@ witness_initialize(void *dummy __unused) (witness_count + 1)); } - for (i = 0; i < LOCK_CHILDCOUNT; i++) - witness_lock_list_free(&w_locklistdata[i]); + witness_init_lock_list(); witness_init_hash_tables(); /* First add in all the specified order lists. */ @@ -2131,21 +2137,35 @@ witness_lock_list_get(void) return (NULL); } w_lock_list_free = lle->ll_next; + lock_list_used++; + if (lock_list_used > lock_list_max_used) + lock_list_max_used = lock_list_used; mtx_unlock_spin(&w_mtx); bzero(lle, sizeof(*lle)); return (lle); } - + static void witness_lock_list_free(struct lock_list_entry *lle) { mtx_lock_spin(&w_mtx); + lock_list_used--; lle->ll_next = w_lock_list_free; w_lock_list_free = lle; mtx_unlock_spin(&w_mtx); } +static void +witness_init_lock_list(void) +{ + int i; + + for (i = 0; i < LOCK_CHILDCOUNT; i++) + witness_lock_list_free(&w_locklistdata[i]); + lock_list_used = 0; +} + static struct lock_instance * find_instance(struct lock_list_entry *list, const struct lock_object *lock) {