summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2018-05-16 14:55:45 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2018-05-16 14:55:45 +0000
commit81de96a485fcec14fb656663afb72ac9269ef0df (patch)
tree3d6c657531cab43dd6ca396388a2c54865ed16bc /sys/kern
parent4f333c3b2e0f1d3454aee26e003bf33ec0fdcdb5 (diff)
Print stack traces on lock order conflict.
OK mpi@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_witness.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index e47ea4a5b13..31a97cb4856 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_witness.c,v 1.14 2018/05/16 14:53:43 visa Exp $ */
+/* $OpenBSD: subr_witness.c,v 1.15 2018/05/16 14:55:44 visa Exp $ */
/*-
* Copyright (c) 2008 Isilon Systems, Inc.
@@ -1039,6 +1039,41 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
lock->lo_name, w->w_type->lt_name,
fixup_filename(file), line);
}
+ if (witness_watch > 1) {
+ struct witness_lock_order_data *wlod1, *wlod2;
+
+ mtx_enter(&w_mtx);
+ wlod1 = witness_lock_order_get(w, w1);
+ wlod2 = witness_lock_order_get(w1, w);
+ mtx_leave(&w_mtx);
+
+ /*
+ * It is safe to access saved stack traces,
+ * w_type, and w_class without the lock.
+ * Once written, they never change.
+ */
+
+ if (wlod1 != NULL) {
+ printf("lock order \"%s\"(%s) -> "
+ "\"%s\"(%s) first seen at:\n",
+ w->w_type->lt_name,
+ w->w_class->lc_name,
+ w1->w_type->lt_name,
+ w1->w_class->lc_name);
+ db_print_stack_trace(
+ &wlod1->wlod_stack, printf);
+ }
+ if (wlod2 != NULL) {
+ printf("lock order \"%s\"(%s) -> "
+ "\"%s\"(%s) first seen at:\n",
+ w1->w_type->lt_name,
+ w1->w_class->lc_name,
+ w->w_type->lt_name,
+ w->w_class->lc_name);
+ db_print_stack_trace(
+ &wlod2->wlod_stack, printf);
+ }
+ }
witness_debugger(0);
goto out_splx;
}