87 #include <sys/cdefs.h>
91 #include "opt_hwpmc_hooks.h"
92 #include "opt_stack.h"
93 #include "opt_witness.h"
95 #include <sys/param.h>
98 #include <sys/kernel.h>
100 #include <sys/lock.h>
101 #include <sys/malloc.h>
102 #include <sys/mutex.h>
103 #include <sys/priv.h>
104 #include <sys/proc.h>
105 #include <sys/sbuf.h>
106 #include <sys/sched.h>
107 #include <sys/stack.h>
108 #include <sys/sysctl.h>
109 #include <sys/systm.h>
115 #include <machine/stdarg.h>
117 #if !defined(DDB) && !defined(STACK)
118 #error "DDB or STACK options are required for WITNESS"
123 #define KTR_WITNESS KTR_SUBSYS
125 #define KTR_WITNESS 0
128 #define LI_RECURSEMASK 0x0000ffff
129 #define LI_EXCLUSIVE 0x00010000
130 #define LI_NORELEASE 0x00020000
135 #define WITNESS_COUNT 1024
136 #define WITNESS_CHILDCOUNT (WITNESS_COUNT * 4)
137 #define WITNESS_HASH_SIZE 251
138 #define WITNESS_PENDLIST 768
141 #define WITNESS_LO_DATA_COUNT 2048
144 #define WITNESS_LO_HASH_SIZE 1021
151 #define LOCK_NCHILDREN 5
152 #define LOCK_CHILDCOUNT 2048
154 #define MAX_W_NAME 64
156 #define BADSTACK_SBUF_SIZE (256 * WITNESS_COUNT)
157 #define FULLGRAPH_SBUF_SIZE 512
163 #define WITNESS_UNRELATED 0x00
164 #define WITNESS_PARENT 0x01
165 #define WITNESS_ANCESTOR 0x02
166 #define WITNESS_CHILD 0x04
167 #define WITNESS_DESCENDANT 0x08
168 #define WITNESS_ANCESTOR_MASK (WITNESS_PARENT | WITNESS_ANCESTOR)
169 #define WITNESS_DESCENDANT_MASK (WITNESS_CHILD | WITNESS_DESCENDANT)
170 #define WITNESS_RELATED_MASK \
171 (WITNESS_ANCESTOR_MASK | WITNESS_DESCENDANT_MASK)
172 #define WITNESS_REVERSAL 0x10
174 #define WITNESS_RESERVED1 0x20
175 #define WITNESS_RESERVED2 0x40
176 #define WITNESS_LOCK_ORDER_KNOWN 0x80
179 #define WITNESS_DTOA(x) (((x) & WITNESS_RELATED_MASK) >> 2)
182 #define WITNESS_ATOD(x) (((x) & WITNESS_RELATED_MASK) << 2)
184 #define WITNESS_INDEX_ASSERT(i) \
185 MPASS((i) > 0 && (i) <= w_max_used_index && (i) < WITNESS_COUNT)
227 STAILQ_ENTRY(
witness) w_typelist;
232 uint16_t w_num_ancestors;
234 uint16_t w_num_descendants;
237 unsigned w_displayed:1;
238 unsigned w_reversed:1;
262 struct stack wlod_stack;
279 struct witness_blessed {
303 return ((w1->
w_class->lc_flags & (LC_SLEEPLOCK | LC_SPINLOCK)) ==
304 (w2->
w_class->lc_flags & (LC_SLEEPLOCK | LC_SPINLOCK)));
318 static void _witness_debugger(
int cond,
const char *msg);
326 struct lock_class *lock_class);
328 struct lock_object *lock);
337 static void witness_ddb_compute_levels(
void);
338 static void witness_ddb_display(
int(*)(
const char *fmt, ...));
339 static void witness_ddb_display_descendants(
int(*)(
const char *fmt, ...),
341 static void witness_ddb_display_list(
int(*prnt)(
const char *fmt, ...),
342 struct witness_list *list);
343 static void witness_ddb_level_descendants(
struct witness *
parent,
int l);
344 static void witness_ddb_list(
struct thread *td);
363 int (*prnt)(
const char *fmt, ...));
367 #define witness_debugger(c) _witness_debugger(c, __func__)
369 #define witness_debugger(c)
383 TUNABLE_INT(
"debug.witness.watch", &witness_watch);
384 SYSCTL_PROC(_debug_witness, OID_AUTO, watch, CTLFLAG_RW | CTLTYPE_INT, NULL, 0,
400 SYSCTL_INT(_debug_witness, OID_AUTO, kdb, CTLFLAG_RW, &witness_kdb, 0,
"");
408 int witness_trace = 1;
409 TUNABLE_INT(
"debug.witness.trace", &witness_trace);
410 SYSCTL_INT(_debug_witness, OID_AUTO, trace, CTLFLAG_RW, &witness_trace, 0,
"");
413 #ifdef WITNESS_SKIPSPIN
416 int witness_skipspin = 0;
418 TUNABLE_INT(
"debug.witness.skipspin", &witness_skipspin);
419 SYSCTL_INT(_debug_witness, OID_AUTO, skipspin, CTLFLAG_RDTUN, &witness_skipspin,
425 SYSCTL_PROC(_debug_witness, OID_AUTO, fullgraph, CTLTYPE_STRING | CTLFLAG_RD,
431 SYSCTL_PROC(_debug_witness, OID_AUTO, badstacks, CTLTYPE_STRING | CTLFLAG_RD,
437 static struct witness_list
w_free = STAILQ_HEAD_INITIALIZER(w_free);
438 static struct witness_list
w_all = STAILQ_HEAD_INITIALIZER(w_all);
441 static struct witness_list
w_spin = STAILQ_HEAD_INITIALIZER(w_spin);
442 static struct witness_list
w_sleep = STAILQ_HEAD_INITIALIZER(w_sleep);
450 SYSCTL_INT(_debug_witness, OID_AUTO, free_cnt, CTLFLAG_RD, &w_free_cnt, 0,
"");
451 SYSCTL_INT(_debug_witness, OID_AUTO, spin_cnt, CTLFLAG_RD, &w_spin_cnt, 0,
"");
452 SYSCTL_INT(_debug_witness, OID_AUTO, sleep_cnt, CTLFLAG_RD, &w_sleep_cnt, 0,
665 #if defined(SMP) && defined(__sparc64__)
680 #if defined(__i386__) || defined(__amd64__)
702 static struct witness_blessed blessed_list[] = {
704 static int blessed_count =
705 sizeof(blessed_list) /
sizeof(
struct witness_blessed);
726 while (strncmp(file,
"../", 3) == 0)
739 struct lock_object *lock;
752 mtx_assert(&
Giant, MA_NOTOWNED);
754 CTR1(
KTR_WITNESS,
"%s: initializing witness", __func__);
755 mtx_init(&
w_mtx,
"witness lock", NULL, MTX_SPIN | MTX_QUIET |
756 MTX_NOWITNESS | MTX_NOPROFILE);
757 for (i = WITNESS_COUNT - 1; i >= 0; i--) {
759 memset(w, 0,
sizeof(*w));
763 KASSERT(STAILQ_FIRST(&w_free)->w_index == 0,
764 (
"%s: Invalid list of free witness objects", __func__));
767 STAILQ_REMOVE_HEAD(&w_free, w_list);
771 (
sizeof(**w_rmatrix) * (WITNESS_COUNT+1) * (WITNESS_COUNT+1)));
778 for (order = order_lists; order->
w_name != NULL; order++) {
782 w->w_file =
"order list";
783 for (order++; order->
w_name != NULL; order++) {
787 w1->w_file =
"order list";
792 witness_spin_warn = 1;
797 KASSERT(lock->lo_flags & LO_WITNESS,
798 (
"%s: lock %s is on pending list but not LO_WITNESS",
799 __func__, lock->lo_name));
815 struct lock_class *
class;
818 class = LOCK_CLASS(lock);
819 if ((lock->lo_flags & LO_RECURSABLE) != 0 &&
820 (class->lc_flags & LC_RECURSABLE) == 0)
821 panic(
"%s: lock (%s) %s can not be recursable", __func__,
822 class->lc_name, lock->lo_name);
823 if ((lock->lo_flags & LO_SLEEPABLE) != 0 &&
824 (class->lc_flags & LC_SLEEPABLE) == 0)
825 panic(
"%s: lock (%s) %s can not be sleepable", __func__,
826 class->lc_name, lock->lo_name);
827 if ((lock->lo_flags & LO_UPGRADABLE) != 0 &&
828 (class->lc_flags & LC_UPGRADABLE) == 0)
829 panic(
"%s: lock (%s) %s can not be upgradable", __func__,
830 class->lc_name, lock->lo_name);
839 if (witness_watch < 1 ||
panicstr != NULL ||
840 (lock->lo_flags & LO_WITNESS) == 0)
841 lock->lo_witness = NULL;
842 else if (witness_cold) {
846 panic(
"%s: pending locks list is too small, bump it\n",
849 lock->lo_witness =
enroll(type,
class);
855 struct lock_class *
class;
858 class = LOCK_CLASS(lock);
861 panic(
"lock (%s) %s destroyed while witness_cold",
862 class->lc_name, lock->lo_name);
865 if ((lock->lo_flags & LO_WITNESS) == 0 || lock->lo_witness == NULL)
867 w = lock->lo_witness;
869 mtx_lock_spin(&
w_mtx);
870 MPASS(w->w_refcount > 0);
873 if (w->w_refcount == 0)
875 mtx_unlock_spin(&
w_mtx);
880 witness_ddb_compute_levels(
void)
887 STAILQ_FOREACH(w, &w_all, w_list)
893 STAILQ_FOREACH(w, &w_all, w_list) {
896 if (w->w_num_ancestors > 0)
898 witness_ddb_level_descendants(w, 0);
903 witness_ddb_level_descendants(
struct witness *w,
int l)
907 if (w->w_ddb_level >= l)
915 witness_ddb_level_descendants(&w_data[i], l);
920 witness_ddb_display_descendants(
int(*prnt)(
const char *fmt, ...),
925 for (i = 0; i < indent; i++)
927 prnt(
"%s (type: %s, depth: %d, active refs: %d)",
929 w->w_ddb_level, w->w_refcount);
930 if (w->w_displayed) {
931 prnt(
" -- (already displayed)\n");
935 if (w->w_file != NULL && w->w_line != 0)
939 prnt(
" -- never acquired\n");
946 witness_ddb_display_descendants(prnt, &w_data[i],
952 witness_ddb_display_list(
int(*prnt)(
const char *fmt, ...),
953 struct witness_list *list)
957 STAILQ_FOREACH(w, list, w_typelist) {
958 if (w->w_file == NULL || w->w_ddb_level > 0)
962 witness_ddb_display_descendants(prnt, w, 0);
969 witness_ddb_display(
int(*prnt)(
const char *fmt, ...))
973 KASSERT(witness_cold == 0, (
"%s: witness_cold", __func__));
974 witness_ddb_compute_levels();
977 STAILQ_FOREACH(w, &w_all, w_list)
984 prnt("Sleep locks:\n");
985 witness_ddb_display_list(prnt, &w_sleep);
992 prnt("\nSpin locks:\n");
993 witness_ddb_display_list(prnt, &w_spin);
1000 prnt("\nLocks which were never acquired:\n");
1001 STAILQ_FOREACH(w, &w_all, w_list) {
1002 if (w->w_file != NULL || w->w_refcount == 0)
1004 prnt(
"%s (type: %s, depth: %d)\n", w->w_name,
1005 w->w_class->lc_name, w->w_ddb_level);
1016 if (witness_watch == -1 ||
panicstr != NULL)
1020 if (lock1 == NULL || lock1->lo_witness == NULL || lock2 == NULL ||
1021 lock2->lo_witness == NULL)
1024 mtx_assert(&
w_mtx, MA_NOTOWNED);
1025 mtx_lock_spin(&
w_mtx);
1031 if (witness_watch &&
1033 mtx_unlock_spin(&
w_mtx);
1038 CTR3(
KTR_WITNESS,
"%s: adding %s as a child of %s", __func__,
1039 lock2->lo_witness->w_name, lock1->lo_witness->w_name);
1040 itismychild(lock1->lo_witness, lock2->lo_witness);
1041 mtx_unlock_spin(&
w_mtx);
1047 int line,
struct lock_object *interlock)
1051 struct lock_class *
class;
1056 if (witness_cold || witness_watch < 1 || lock->lo_witness == NULL ||
1060 w = lock->lo_witness;
1061 class = LOCK_CLASS(lock);
1064 if (class->lc_flags & LC_SLEEPLOCK) {
1072 panic(
"blockable sleep lock (%s) %s @ %s:%d",
1073 class->lc_name, lock->lo_name,
1080 lock_list = td->td_sleeplocks;
1081 if (lock_list == NULL || lock_list->
ll_count == 0)
1094 lock_list = PCPU_GET(spinlocks);
1095 if (lock_list == NULL || lock_list->
ll_count == 0) {
1108 if (lock1 != NULL) {
1110 (flags & LOP_EXCLUSIVE) == 0) {
1111 printf(
"shared lock of (%s) %s @ %s:%d\n",
1112 class->lc_name, lock->lo_name,
1114 printf(
"while exclusively locked from %s:%d\n",
1116 panic(
"share->excl");
1119 (flags & LOP_EXCLUSIVE) != 0) {
1120 printf(
"exclusive lock of (%s) %s @ %s:%d\n",
1121 class->lc_name, lock->lo_name,
1123 printf(
"while share locked from %s:%d\n",
1125 panic(
"excl->share");
1134 if (interlock != NULL && plock->
li_lock == interlock) {
1155 w1 = plock->
li_lock->lo_witness;
1164 mtx_lock_spin(&
w_mtx);
1168 if (!(lock->lo_flags & LO_DUPOK) && !(flags & LOP_DUPOK) &&
1172 mtx_unlock_spin(&
w_mtx);
1174 "acquiring duplicate lock of same type: \"%s\"\n",
1178 printf(
" 2nd %s @ %s:%d\n", lock->lo_name,
1182 mtx_unlock_spin(&
w_mtx);
1185 mtx_assert(&
w_mtx, MA_OWNED);
1195 for (j = 0, lle = lock_list; lle != NULL; lle = lle->
ll_next) {
1196 for (i = lle->
ll_count - 1; i >= 0; i--, j++) {
1204 if (interlock != NULL && interlock == lock1->
li_lock) {
1213 w1 = lock1->
li_lock->lo_witness;
1215 KASSERT((lock1->
li_lock->lo_flags & LO_WITNESS) == 0,
1216 (
"lock missing witness structure"));
1224 if ((lock1->
li_lock->lo_flags & LO_SLEEPABLE) != 0 &&
1225 lock == &
Giant.lock_object)
1232 if ((lock->lo_flags & LO_SLEEPABLE) != 0 &&
1242 if (((lock->lo_flags & LO_SLEEPABLE) != 0 &&
1243 (lock1->
li_lock->lo_flags & LO_SLEEPABLE) == 0))
1250 if ((lock1->
li_lock->lo_flags & LO_SLEEPABLE) == 0 &&
1251 lock == &
Giant.lock_object)
1283 w->w_reversed = w1->w_reversed = 1;
1285 mtx_unlock_spin(&
w_mtx);
1290 if (((lock->lo_flags & LO_SLEEPABLE) != 0 &&
1291 (lock1->
li_lock->lo_flags & LO_SLEEPABLE) == 0))
1293 "lock order reversal: (sleepable after non-sleepable)\n");
1294 else if ((lock1->
li_lock->lo_flags & LO_SLEEPABLE) == 0
1295 && lock == &
Giant.lock_object)
1297 "lock order reversal: (Giant after non-sleepable)\n");
1299 printf(
"lock order reversal:\n");
1307 MPASS(lock2->
li_lock != NULL);
1308 if (lock2->
li_lock->lo_witness == w)
1310 if (i == 0 && lle->
ll_next != NULL) {
1318 printf(
" 1st %p %s (%s) @ %s:%d\n",
1322 printf(
" 2nd %p %s (%s) @ %s:%d\n", lock,
1323 lock->lo_name, w->
w_name,
1326 printf(
" 1st %p %s (%s) @ %s:%d\n",
1328 lock2->
li_lock->lo_witness->w_name,
1331 printf(
" 2nd %p %s (%s) @ %s:%d\n",
1335 printf(
" 3rd %p %s (%s) @ %s:%d\n", lock,
1336 lock->lo_name, w->
w_name,
1350 if (flags & LOP_NEWORDER &&
1352 (lock->lo_flags & LO_SLEEPABLE) != 0)) {
1353 CTR3(
KTR_WITNESS,
"%s: adding %s as a child of %s", __func__,
1358 mtx_unlock_spin(&
w_mtx);
1362 witness_lock(
struct lock_object *lock,
int flags,
const char *file,
int line)
1369 if (witness_cold || witness_watch == -1 || lock->lo_witness == NULL ||
1372 w = lock->lo_witness;
1376 if (LOCK_CLASS(lock)->lc_flags & LC_SLEEPLOCK)
1377 lock_list = &td->td_sleeplocks;
1379 lock_list = PCPU_PTR(spinlocks);
1383 if (instance != NULL) {
1385 CTR4(
KTR_WITNESS,
"%s: pid %d recursed on %s r=%d", __func__,
1386 td->td_proc->p_pid, lock->lo_name,
1404 CTR3(
KTR_WITNESS,
"%s: pid %d added lle %p", __func__,
1405 td->td_proc->p_pid, lle);
1412 if ((flags & LOP_EXCLUSIVE) != 0)
1416 CTR4(
KTR_WITNESS,
"%s: pid %d added %s as lle[%d]", __func__,
1417 td->td_proc->p_pid, lock->lo_name, lle->
ll_count - 1);
1424 struct lock_class *
class;
1426 KASSERT(witness_cold == 0, (
"%s: witness_cold", __func__));
1427 if (lock->lo_witness == NULL || witness_watch == -1 ||
panicstr != NULL)
1429 class = LOCK_CLASS(lock);
1430 if (witness_watch) {
1431 if ((lock->lo_flags & LO_UPGRADABLE) == 0)
1432 panic(
"upgrade of non-upgradable lock (%s) %s @ %s:%d",
1433 class->lc_name, lock->lo_name,
1435 if ((class->lc_flags & LC_SLEEPLOCK) == 0)
1436 panic(
"upgrade of non-sleep lock (%s) %s @ %s:%d",
1437 class->lc_name, lock->lo_name,
1441 if (instance == NULL)
1442 panic(
"upgrade of unlocked lock (%s) %s @ %s:%d",
1443 class->lc_name, lock->lo_name,
1445 if (witness_watch) {
1447 panic(
"upgrade of exclusive lock (%s) %s @ %s:%d",
1448 class->lc_name, lock->lo_name,
1451 panic(
"upgrade of recursed lock (%s) %s r=%d @ %s:%d",
1452 class->lc_name, lock->lo_name,
1464 struct lock_class *
class;
1466 KASSERT(witness_cold == 0, (
"%s: witness_cold", __func__));
1467 if (lock->lo_witness == NULL || witness_watch == -1 ||
panicstr != NULL)
1469 class = LOCK_CLASS(lock);
1470 if (witness_watch) {
1471 if ((lock->lo_flags & LO_UPGRADABLE) == 0)
1472 panic(
"downgrade of non-upgradable lock (%s) %s @ %s:%d",
1473 class->lc_name, lock->lo_name,
1475 if ((class->lc_flags & LC_SLEEPLOCK) == 0)
1476 panic(
"downgrade of non-sleep lock (%s) %s @ %s:%d",
1477 class->lc_name, lock->lo_name,
1481 if (instance == NULL)
1482 panic(
"downgrade of unlocked lock (%s) %s @ %s:%d",
1483 class->lc_name, lock->lo_name,
1485 if (witness_watch) {
1487 panic(
"downgrade of shared lock (%s) %s @ %s:%d",
1488 class->lc_name, lock->lo_name,
1491 panic(
"downgrade of recursed lock (%s) %s r=%d @ %s:%d",
1492 class->lc_name, lock->lo_name,
1504 struct lock_class *
class;
1509 if (witness_cold || lock->lo_witness == NULL ||
panicstr != NULL)
1512 class = LOCK_CLASS(lock);
1515 if (class->lc_flags & LC_SLEEPLOCK)
1516 lock_list = &td->td_sleeplocks;
1518 lock_list = PCPU_PTR(spinlocks);
1520 for (; *lock_list != NULL; lock_list = &(*lock_list)->
ll_next)
1521 for (i = 0; i < (*lock_list)->ll_count; i++) {
1522 instance = &(*lock_list)->ll_children[i];
1523 if (instance->
li_lock == lock)
1533 if (witness_watch > 0)
1534 panic(
"lock (%s) %s not locked @ %s:%d", class->lc_name,
1542 (flags & LOP_EXCLUSIVE) == 0) {
1543 printf(
"shared unlock of (%s) %s @ %s:%d\n", class->lc_name,
1545 printf(
"while exclusively locked from %s:%d\n",
1547 panic(
"excl->ushare");
1550 (flags & LOP_EXCLUSIVE) != 0) {
1551 printf(
"exclusive unlock of (%s) %s @ %s:%d\n", class->lc_name,
1553 printf(
"while share locked from %s:%d\n",
1556 panic(
"share->uexcl");
1560 CTR4(
KTR_WITNESS,
"%s: pid %d unrecursed on %s r=%d", __func__,
1561 td->td_proc->p_pid, instance->
li_lock->lo_name,
1568 printf(
"forbidden unlock of (%s) %s @ %s:%d\n", class->lc_name,
1570 panic(
"lock marked norelease");
1575 CTR4(
KTR_WITNESS,
"%s: pid %d removed %s from lle[%d]", __func__,
1576 td->td_proc->p_pid, instance->
li_lock->lo_name,
1577 (*lock_list)->ll_count - 1);
1578 for (j = i; j < (*lock_list)->ll_count - 1; j++)
1579 (*lock_list)->ll_children[j] =
1580 (*lock_list)->ll_children[j + 1];
1581 (*lock_list)->ll_count--;
1593 if ((*lock_list)->ll_count == 0) {
1594 if (*lock_list == lle) {
1600 CTR3(
KTR_WITNESS,
"%s: pid %d removed lle %p", __func__,
1601 td->td_proc->p_pid, lle);
1612 lle = td->td_sleeplocks;
1613 if (lle == NULL ||
panicstr != NULL)
1616 for (n = 0; lle != NULL; lle = lle->
ll_next)
1617 for (i = lle->
ll_count - 1; i >= 0; i--) {
1619 printf(
"Thread %p exiting with the following locks held:\n",
1625 panic(
"Thread %p cannot exit while holding sleeplocks\n", td);
1646 if (witness_cold || witness_watch < 1 ||
panicstr != NULL)
1650 for (lle = td->td_sleeplocks; lle != NULL; lle = lle->
ll_next)
1651 for (i = lle->
ll_count - 1; i >= 0; i--) {
1655 if (flags & WARN_GIANTOK &&
1658 if (flags & WARN_SLEEPOK &&
1659 (lock1->
li_lock->lo_flags & LO_SLEEPABLE) != 0)
1665 printf(
" with the following");
1666 if (flags & WARN_SLEEPOK)
1667 printf(
" non-sleepable");
1668 printf(
" locks held:\n");
1680 lock_list = PCPU_GET(spinlocks);
1681 if (lock_list != NULL && lock_list->
ll_count != 0) {
1692 lock1->
li_lock == lock && n == 0)
1698 printf(
" with the following");
1699 if (flags & WARN_SLEEPOK)
1700 printf(
" non-sleepable");
1701 printf(
" locks held:\n");
1705 if (flags & WARN_PANIC && n)
1706 panic(
"%s", __func__);
1717 if (witness_cold || witness_watch < 1 || lock->lo_witness == NULL)
1719 w = lock->lo_witness;
1728 if (witness_cold || witness_watch < 1 || lock->lo_witness == NULL)
1730 w = lock->lo_witness;
1735 enroll(
const char *description,
struct lock_class *lock_class)
1738 struct witness_list *typelist;
1740 MPASS(description != NULL);
1742 if (witness_watch == -1 ||
panicstr != NULL)
1744 if ((lock_class->lc_flags & LC_SPINLOCK)) {
1745 if (witness_skipspin)
1749 }
else if ((lock_class->lc_flags & LC_SLEEPLOCK))
1752 panic(
"lock class %s is not sleep or spin",
1753 lock_class->lc_name);
1755 mtx_lock_spin(&
w_mtx);
1762 strcpy(w->
w_name, description);
1765 STAILQ_INSERT_HEAD(&w_all, w, w_list);
1766 if (lock_class->lc_flags & LC_SPINLOCK) {
1767 STAILQ_INSERT_HEAD(&w_spin, w, w_typelist);
1769 }
else if (lock_class->lc_flags & LC_SLEEPLOCK) {
1770 STAILQ_INSERT_HEAD(&w_sleep, w, w_typelist);
1777 mtx_unlock_spin(&
w_mtx);
1781 mtx_unlock_spin(&
w_mtx);
1784 "lock (%s) %s does not match earlier (%s) lock",
1785 description, lock_class->lc_name,
1793 struct witness_list *list;
1795 MPASS(w->w_refcount == 0);
1796 if (w->
w_class->lc_flags & LC_SLEEPLOCK) {
1817 if (witness_cold == 0)
1818 mtx_assert(&
w_mtx, MA_OWNED);
1844 parent->w_num_descendants++;
1845 child->w_num_ancestors++;
1864 if (w_rmatrix[i][j] & WITNESS_ANCESTOR_MASK)
1871 if ((w_rmatrix[ci][j] & WITNESS_ANCESTOR_MASK) == 0 &&
1876 w_data[i].w_num_descendants++;
1877 w_data[j].w_num_ancestors++;
1884 if ((w_rmatrix[i][j] & WITNESS_ANCESTOR_MASK) &&
1886 printf(
"witness rmatrix paradox! [%d][%d]=%d "
1887 "both ancestor and descendant\n",
1888 i, j, w_rmatrix[i][j]);
1890 printf(
"Witness disabled.\n");
1893 if ((w_rmatrix[j][i] & WITNESS_ANCESTOR_MASK) &&
1894 (w_rmatrix[j][i] & WITNESS_DESCENDANT_MASK)) {
1895 printf(
"witness rmatrix paradox! [%d][%d]=%d "
1896 "both ancestor and descendant\n",
1897 j, i, w_rmatrix[j][i]);
1899 printf(
"Witness disabled.\n");
1910 MPASS(child != NULL && parent != NULL);
1911 if (witness_cold == 0)
1912 mtx_assert(&
w_mtx, MA_OWNED);
1915 if (witness_cold == 0)
1916 mtx_unlock_spin(&
w_mtx);
1917 panic(
"%s: parent \"%s\" (%s) and child \"%s\" (%s) are not "
1918 "the same lock type", __func__, parent->
w_name,
1922 adopt(parent, child);
1932 unsigned char r1, r2;
1945 printf(
"%s: rmatrix mismatch between %s (index %d) and %s "
1946 "(index %d): w_rmatrix[%d][%d] == %hhx but "
1947 "w_rmatrix[%d][%d] == %hhx\n",
1951 printf(
"Witness disabled.\n");
1954 return (r1 & rmask);
1983 struct witness_blessed *b;
1985 for (i = 0; i < blessed_count; i++) {
1986 b = &blessed_list[i];
1987 if (strcmp(w1->
w_name, b->b_lock1) == 0) {
1988 if (strcmp(w2->
w_name, b->b_lock2) == 0)
1992 if (strcmp(w1->
w_name, b->b_lock2) == 0)
1993 if (strcmp(w2->
w_name, b->b_lock1) == 0)
2006 if (witness_cold == 0)
2007 mtx_assert(&
w_mtx, MA_OWNED);
2009 if (witness_watch == -1) {
2010 mtx_unlock_spin(&
w_mtx);
2013 if (STAILQ_EMPTY(&w_free)) {
2015 mtx_unlock_spin(&
w_mtx);
2016 printf(
"WITNESS: unable to allocate a new witness object\n");
2019 w = STAILQ_FIRST(&w_free);
2020 STAILQ_REMOVE_HEAD(&w_free, w_list);
2023 MPASS(index > 0 && index == w_max_used_index+1 &&
2025 bzero(w,
sizeof(*w));
2027 if (index > w_max_used_index)
2028 w_max_used_index = index;
2036 STAILQ_INSERT_HEAD(&w_free, w, w_list);
2045 if (witness_watch == -1)
2047 mtx_lock_spin(&
w_mtx);
2051 mtx_unlock_spin(&
w_mtx);
2052 printf(
"%s: witness exhausted\n", __func__);
2055 w_lock_list_free = lle->
ll_next;
2056 mtx_unlock_spin(&
w_mtx);
2057 bzero(lle,
sizeof(*lle));
2065 mtx_lock_spin(&
w_mtx);
2067 w_lock_list_free = lle;
2068 mtx_unlock_spin(&
w_mtx);
2078 for (lle = list; lle != NULL; lle = lle->
ll_next)
2079 for (i = lle->
ll_count - 1; i >= 0; i--) {
2081 if (instance->
li_lock == lock)
2089 int (*prnt)(
const char *fmt, ...))
2091 struct lock_object *lock;
2095 "exclusive" :
"shared", LOCK_CLASS(lock)->lc_name, lock->lo_name);
2096 if (lock->lo_witness->w_name != lock->lo_name)
2097 prnt(
" (%s)", lock->lo_witness->w_name);
2098 prnt(
" r = %d (%p) locked @ %s:%d\n",
2105 witness_thread_has_locks(
struct thread *td)
2108 if (td->td_sleeplocks == NULL)
2110 return (td->td_sleeplocks->ll_count != 0);
2114 witness_proc_has_locks(
struct proc *p)
2118 FOREACH_THREAD_IN_PROC(p, td) {
2119 if (witness_thread_has_locks(td))
2128 int (*prnt)(
const char *fmt, ...))
2134 for (lle = *lock_list; lle != NULL; lle = lle->
ll_next)
2135 for (i = lle->
ll_count - 1; i >= 0; i--) {
2151 int (*prnt)(
const char *fmt, ...))
2156 if (owner->td_critnest == 0 || owner->td_oncpu == NOCPU)
2160 if (instance != NULL)
2169 struct lock_class *
class;
2176 if (SCHEDULER_STOPPED())
2178 KASSERT(witness_cold == 0, (
"%s: witness_cold", __func__));
2179 if (lock->lo_witness == NULL || witness_watch == -1 ||
panicstr != NULL)
2181 class = LOCK_CLASS(lock);
2182 if (class->lc_flags & LC_SLEEPLOCK)
2183 lock_list = curthread->td_sleeplocks;
2185 if (witness_skipspin)
2187 lock_list = PCPU_GET(spinlocks);
2190 if (instance == NULL)
2191 panic(
"%s: lock (%s) %s not locked", __func__,
2192 class->lc_name, lock->lo_name);
2202 struct lock_class *
class;
2209 if (SCHEDULER_STOPPED())
2211 KASSERT(witness_cold == 0, (
"%s: witness_cold", __func__));
2212 if (lock->lo_witness == NULL || witness_watch == -1 ||
panicstr != NULL)
2214 class = LOCK_CLASS(lock);
2215 if (class->lc_flags & LC_SLEEPLOCK)
2216 lock_list = curthread->td_sleeplocks;
2218 if (witness_skipspin)
2220 lock_list = PCPU_GET(spinlocks);
2223 if (instance == NULL)
2224 panic(
"%s: lock (%s) %s not locked", __func__,
2225 class->lc_name, lock->lo_name);
2226 lock->lo_witness->w_file = file;
2227 lock->lo_witness->w_line = line;
2235 #ifdef INVARIANT_SUPPORT
2237 struct lock_class *
class;
2239 if (lock->lo_witness == NULL || witness_watch < 1 ||
panicstr != NULL)
2241 class = LOCK_CLASS(lock);
2242 if ((class->lc_flags & LC_SLEEPLOCK) != 0)
2244 else if ((class->lc_flags & LC_SPINLOCK) != 0)
2247 panic(
"Lock (%s) %s is not sleep or spin!",
2248 class->lc_name, lock->lo_name);
2252 if (instance != NULL)
2253 panic(
"Lock (%s) %s locked @ %s:%d.",
2254 class->lc_name, lock->lo_name,
2258 case LA_LOCKED | LA_RECURSED:
2259 case LA_LOCKED | LA_NOTRECURSED:
2261 case LA_SLOCKED | LA_RECURSED:
2262 case LA_SLOCKED | LA_NOTRECURSED:
2264 case LA_XLOCKED | LA_RECURSED:
2265 case LA_XLOCKED | LA_NOTRECURSED:
2266 if (instance == NULL) {
2267 panic(
"Lock (%s) %s not locked @ %s:%d.",
2268 class->lc_name, lock->lo_name,
2272 if ((flags & LA_XLOCKED) != 0 &&
2274 panic(
"Lock (%s) %s not exclusively locked @ %s:%d.",
2275 class->lc_name, lock->lo_name,
2277 if ((flags & LA_SLOCKED) != 0 &&
2279 panic(
"Lock (%s) %s exclusively locked @ %s:%d.",
2280 class->lc_name, lock->lo_name,
2282 if ((flags & LA_RECURSED) != 0 &&
2284 panic(
"Lock (%s) %s not recursed @ %s:%d.",
2285 class->lc_name, lock->lo_name,
2287 if ((flags & LA_NOTRECURSED) != 0 &&
2289 panic(
"Lock (%s) %s recursed @ %s:%d.",
2290 class->lc_name, lock->lo_name,
2294 panic(
"Invalid lock assertion at %s:%d.",
2306 struct lock_class *
class;
2308 if (lock->lo_witness == NULL || witness_watch == -1 ||
panicstr != NULL)
2310 class = LOCK_CLASS(lock);
2311 if (class->lc_flags & LC_SLEEPLOCK)
2312 lock_list = curthread->td_sleeplocks;
2314 if (witness_skipspin)
2316 lock_list = PCPU_GET(spinlocks);
2319 if (instance == NULL)
2320 panic(
"%s: lock (%s) %s not locked", __func__,
2321 class->lc_name, lock->lo_name);
2345 witness_ddb_list(
struct thread *td)
2348 KASSERT(witness_cold == 0, (
"%s: witness_cold", __func__));
2349 KASSERT(
kdb_active, (
"%s: not in the debugger", __func__));
2351 if (witness_watch < 1)
2369 if (td == curthread && PCPU_GET(spinlocks) != NULL)
2373 DB_SHOW_COMMAND(locks, db_witness_list)
2378 td = db_lookup_thread(addr, TRUE);
2381 witness_ddb_list(td);
2384 DB_SHOW_ALL_COMMAND(locks, db_witness_list_all)
2394 FOREACH_PROC_IN_SYSTEM(p) {
2395 if (!witness_proc_has_locks(p))
2397 FOREACH_THREAD_IN_PROC(p, td) {
2398 if (!witness_thread_has_locks(td))
2400 db_printf(
"Process %d (%s) thread %p (%d)\n", p->p_pid,
2401 p->p_comm, td, td->td_tid);
2402 witness_ddb_list(td);
2408 DB_SHOW_ALIAS(alllocks, db_witness_list_all)
2410 DB_SHOW_COMMAND(
witness, db_witness_display)
2413 witness_ddb_display(db_printf);
2421 struct witness *tmp_w1, *tmp_w2, *w1, *w2;
2423 u_int w_rmatrix1, w_rmatrix2;
2424 int error, generation, i, j;
2430 if (witness_watch < 1) {
2431 error = SYSCTL_OUT(req, w_notrunning,
sizeof(w_notrunning));
2435 error = SYSCTL_OUT(req, w_stillcold,
sizeof(w_stillcold));
2444 tmp_w1 =
malloc(
sizeof(
struct witness), M_TEMP, M_WAITOK | M_ZERO);
2445 tmp_w2 =
malloc(
sizeof(
struct witness), M_TEMP, M_WAITOK | M_ZERO);
2454 mtx_lock_spin(&
w_mtx);
2456 mtx_unlock_spin(&
w_mtx);
2457 sbuf_printf(sb,
"Number of known direct relationships is %d\n",
2460 mtx_lock_spin(&
w_mtx);
2461 if (generation != w_generation) {
2462 mtx_unlock_spin(&
w_mtx);
2471 if (w1->w_reversed == 0) {
2472 mtx_unlock_spin(&
w_mtx);
2478 mtx_unlock_spin(&
w_mtx);
2480 if (tmp_w1->w_reversed == 0)
2486 mtx_lock_spin(&
w_mtx);
2487 if (generation != w_generation) {
2488 mtx_unlock_spin(&
w_mtx);
2505 w_rmatrix1 = (
unsigned int)w_rmatrix[i][j];
2506 w_rmatrix2 = (
unsigned int)w_rmatrix[j][i];
2513 if (data2 && data2 != data1) {
2518 mtx_unlock_spin(&
w_mtx);
2521 "\nLock order reversal between \"%s\"(%s) and \"%s\"(%s)!\n",
2526 "w_rmatrix[%s][%s] == %x, w_rmatrix[%s][%s] == %x\n",
2527 tmp_w1->name, tmp_w2->
w_name, w_rmatrix1,
2528 tmp_w2->name, tmp_w1->
w_name, w_rmatrix2);
2532 "Lock order \"%s\"(%s) -> \"%s\"(%s) first seen at:\n",
2538 if (data2 && data2 != data1) {
2540 "Lock order \"%s\"(%s) -> \"%s\"(%s) first seen at:\n",
2548 mtx_lock_spin(&
w_mtx);
2549 if (generation != w_generation) {
2550 mtx_unlock_spin(&
w_mtx);
2560 mtx_unlock_spin(&
w_mtx);
2563 free(tmp_data1, M_TEMP);
2564 free(tmp_data2, M_TEMP);
2565 free(tmp_w1, M_TEMP);
2566 free(tmp_w2, M_TEMP);
2582 if (witness_watch < 1) {
2583 error = SYSCTL_OUT(req, w_notrunning,
sizeof(w_notrunning));
2587 error = SYSCTL_OUT(req, w_stillcold,
sizeof(w_stillcold));
2600 mtx_lock_spin(&
w_mtx);
2601 STAILQ_FOREACH(w, &w_all, w_list)
2603 STAILQ_FOREACH(w, &w_all, w_list)
2605 mtx_unlock_spin(&
w_mtx);
2623 if (error != 0 || req->newptr == NULL)
2625 if (value > 1 || value < -1 ||
2626 (witness_watch == -1 && value != witness_watch))
2628 witness_watch =
value;
2637 if (w->w_displayed != 0 || (w->w_file == NULL && w->w_line == 0))
2660 unsigned int hash = 5381;
2665 for (i = 0; i < size; i++)
2666 hash = ((hash << 5) + hash) + (
unsigned int)key[i];
2668 for (i = 0; key[i] != 0; i++)
2669 hash = ((hash << 5) + hash) + (
unsigned int)key[i];
2684 MPASS(witness_cold);
2713 if (witness_cold == 0)
2714 mtx_assert(&
w_mtx, MA_OWNED);
2718 if (strcmp(w->
w_name, key) == 0)
2733 MPASS(w->
w_name != NULL);
2734 if (witness_cold == 0)
2735 mtx_assert(&
w_mtx, MA_OWNED);
2737 (
"%s: trying to add a hash entry that already exists!", __func__));
2738 KASSERT(w->w_hash_next == NULL,
2739 (
"%s: w->w_hash_next != NULL", __func__));
2755 MPASS(parent != NULL && child != NULL);
2767 while (data != NULL) {
2786 if (parent != child &&
2802 MPASS(parent != NULL && child != NULL);
2832 if (witness_cold == 0)
2833 mtx_assert(&
w_mtx, MA_OWNED);
2839 _witness_debugger(
int cond,
const char *msg)
2842 if (witness_trace && cond)
2844 if (witness_kdb && cond)
static void witness_free(struct witness *m)
static struct lock_instance * find_instance(struct lock_list_entry *list, struct lock_object *lock)
void witness_upgrade(struct lock_object *lock, int flags, const char *file, int line)
#define WITNESS_HASH_SIZE
#define BADSTACK_SBUF_SIZE
static struct witness_pendhelp pending_locks[WITNESS_PENDLIST]
static void witness_add_fullgraph(struct sbuf *sb, struct witness *parent)
struct lock_class lock_class_mtx_spin
void witness_downgrade(struct lock_object *lock, int flags, const char *file, int line)
SYSCTL_INT(_debug_witness, OID_AUTO, skipspin, CTLFLAG_RDTUN,&witness_skipspin, 0,"")
static void witness_hash_put(struct witness *w)
void witness_assert(struct lock_object *lock, int flags, const char *file, int line)
static void witness_initialize(void *dummy __unused)
ssize_t sbuf_len(struct sbuf *s)
void stack_sbuf_print(struct sbuf *sb, struct stack *st)
static int sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS)
static const char * fixup_filename(const char *file)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
#define WITNESS_DESCENDANT
void witness_init(struct lock_object *lock, const char *type)
#define WITNESS_ANCESTOR_MASK
struct lock_object * li_lock
struct lock_class lock_class_rw
void panic(const char *fmt,...)
void witness_thread_exit(struct thread *td)
struct lock_list_entry * ll_next
static struct witness_list w_sleep
struct pcpu * pcpu_find(u_int cpuid)
STAILQ_HEAD(witness_list, witness)
struct lock_object * wh_lock
static int isitmydescendant(struct witness *parent, struct witness *child)
static __inline int witness_lock_type_equal(struct witness *w1, struct witness *w2)
static struct witness * witness_hash_get(const char *key)
static struct witness * w_data
void witness_releaseok(struct lock_object *lock)
struct lock_class * w_class
void witness_norelease(struct lock_object *lock)
struct witness_lock_order_data * wlod_next
static struct witness_order_list_entry order_lists[]
void witness_restore(struct lock_object *lock, const char *file, int line)
int witness_list_locks(struct lock_list_entry **lock_list, int(*prnt)(const char *fmt,...))
void witness_destroy(struct lock_object *lock)
static uint32_t witness_hash_djb2(const uint8_t *key, uint32_t size)
static const char w_notrunning[]
static struct witness_lock_order_data w_lodata[WITNESS_LO_DATA_COUNT]
static int _isitmyx(struct witness *w1, struct witness *w2, int rmask, const char *fname)
static int w_max_used_index
#define WITNESS_LO_DATA_COUNT
int witness_defineorder(struct lock_object *lock1, struct lock_object *lock2)
static void witness_setflag(struct lock_object *lock, int flag, int set)
void sbuf_clear(struct sbuf *s)
SYSINIT(witness_init, SI_SUB_WITNESS, SI_ORDER_FIRST, witness_initialize, NULL)
static struct witness_list w_all
static SYSCTL_NODE(_debug, OID_AUTO, witness, CTLFLAG_RW, NULL,"Witness Locking")
static struct witness * enroll(const char *description, struct lock_class *lock_class)
#define witness_debugger(c)
void stack_zero(struct stack *st)
static int witness_spin_warn
void witness_checkorder(struct lock_object *lock, int flags, const char *file, int line, struct lock_object *interlock)
int sbuf_printf(struct sbuf *s, const char *fmt,...)
static MALLOC_DEFINE(M_WITNESS,"Witness","Witness")
static void itismychild(struct witness *parent, struct witness *child)
struct lock_class lock_class_sx
struct witness_lock_order_key wlod_key
static int witness_lock_order_check(struct witness *parent, struct witness *child)
static void witness_increment_graph_generation(void)
static struct witness_hash w_hash
static int isitmychild(struct witness *parent, struct witness *child)
static __inline int witness_lock_order_key_equal(const struct witness_lock_order_key *a, const struct witness_lock_order_key *b)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
static struct lock_list_entry w_locklistdata[LOCK_CHILDCOUNT]
static uint8_t w_rmatrix[WITNESS_COUNT+1][WITNESS_COUNT+1]
#define WITNESS_RELATED_MASK
static struct lock_list_entry * witness_lock_list_get(void)
struct lock_instance ll_children[LOCK_NCHILDREN]
static struct witness * witness_get(void)
const char * witness_file(struct lock_object *lock)
SYSCTL_PROC(_debug_witness, OID_AUTO, watch, CTLFLAG_RW|CTLTYPE_INT, NULL, 0, sysctl_debug_witness_watch,"I","witness is watching lock operations")
static struct lock_list_entry * w_lock_list_free
struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags)
int witness_line(struct lock_object *lock)
struct lock_class lock_class_mtx_sleep
struct thread * kdb_thread
static int sysctl_debug_witness_watch(SYSCTL_HANDLER_ARGS)
static void depart(struct witness *w)
void stack_copy(struct stack *src, struct stack *dst)
void free(void *addr, struct malloc_type *mtp)
void kdb_enter(const char *why, const char *msg)
static void witness_init_hash_tables(void)
int printf(const char *fmt,...)
#define FULLGRAPH_SBUF_SIZE
void witness_lock(struct lock_object *lock, int flags, const char *file, int line)
int witness_warn(int flags, struct lock_object *lock, const char *fmt,...)
void sbuf_delete(struct sbuf *s)
static const char w_stillcold[]
void witness_unlock(struct lock_object *lock, int flags, const char *file, int line)
static int witness_lock_order_add(struct witness *parent, struct witness *child)
static void witness_lock_list_free(struct lock_list_entry *lle)
static void adopt(struct witness *parent, struct witness *child)
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
void witness_display_spinlock(struct lock_object *lock, struct thread *owner, int(*prnt)(const char *fmt,...))
static void witness_list_lock(struct lock_instance *instance, int(*prnt)(const char *fmt,...))
void mtx_init(struct mtx *m, const char *name, const char *type, int opts)
void witness_save(struct lock_object *lock, const char **filep, int *linep)
#define WITNESS_INDEX_ASSERT(i)
struct witness * wh_array[WITNESS_HASH_SIZE]
static int sysctl_debug_witness_fullgraph(SYSCTL_HANDLER_ARGS)
char * sbuf_data(struct sbuf *s)
int sbuf_finish(struct sbuf *s)
struct lock_class * w_class
static struct witness_lock_order_data * witness_lock_order_get(struct witness *parent, struct witness *child)
#define WITNESS_LOCK_ORDER_KNOWN
int vprintf(const char *fmt, va_list ap)
static struct witness_list w_free
static struct witness_list w_spin
struct witness_lock_order_data * wloh_array[WITNESS_LO_HASH_SIZE]
static struct witness_lock_order_data * w_lofree
TUNABLE_INT("debug.witness.watch",&witness_watch)
static unsigned int w_generation
static struct witness_lock_order_hash w_lohash
#define WITNESS_LO_HASH_SIZE
struct sbuf * sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, struct sysctl_req *req)
#define WITNESS_DESCENDANT_MASK