mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
Switch the hardwired WITNESS panics to kassert_panic.
This is an ongoing effort to provide runtime debug information useful in the field that does not panic existing installations. This gives us the flexibility needed when shipping images to a potentially large audience with WITNESS enabled without worrying about formerly non-fatal LORs hurting a release. Sponsored by: iXsystems
This commit is contained in:
parent
aae7510122
commit
6b6bd3b704
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=244105
@ -540,7 +540,7 @@ shutdown_reset(void *junk, int howto)
|
||||
/* NOTREACHED */ /* assuming reset worked */
|
||||
}
|
||||
|
||||
#ifdef INVARIANTS
|
||||
#if defined(WITNESS) || defined(INVARIANTS)
|
||||
static int kassert_warn_only = 0;
|
||||
#ifdef KDB
|
||||
static int kassert_do_kdb = 0;
|
||||
|
@ -822,16 +822,16 @@ witness_init(struct lock_object *lock, const char *type)
|
||||
class = LOCK_CLASS(lock);
|
||||
if ((lock->lo_flags & LO_RECURSABLE) != 0 &&
|
||||
(class->lc_flags & LC_RECURSABLE) == 0)
|
||||
panic("%s: lock (%s) %s can not be recursable", __func__,
|
||||
class->lc_name, lock->lo_name);
|
||||
kassert_panic("%s: lock (%s) %s can not be recursable",
|
||||
__func__, class->lc_name, lock->lo_name);
|
||||
if ((lock->lo_flags & LO_SLEEPABLE) != 0 &&
|
||||
(class->lc_flags & LC_SLEEPABLE) == 0)
|
||||
panic("%s: lock (%s) %s can not be sleepable", __func__,
|
||||
class->lc_name, lock->lo_name);
|
||||
kassert_panic("%s: lock (%s) %s can not be sleepable",
|
||||
__func__, class->lc_name, lock->lo_name);
|
||||
if ((lock->lo_flags & LO_UPGRADABLE) != 0 &&
|
||||
(class->lc_flags & LC_UPGRADABLE) == 0)
|
||||
panic("%s: lock (%s) %s can not be upgradable", __func__,
|
||||
class->lc_name, lock->lo_name);
|
||||
kassert_panic("%s: lock (%s) %s can not be upgradable",
|
||||
__func__, class->lc_name, lock->lo_name);
|
||||
|
||||
/*
|
||||
* If we shouldn't watch this lock, then just clear lo_witness.
|
||||
@ -847,7 +847,8 @@ witness_init(struct lock_object *lock, const char *type)
|
||||
pending_locks[pending_cnt].wh_lock = lock;
|
||||
pending_locks[pending_cnt++].wh_type = type;
|
||||
if (pending_cnt > WITNESS_PENDLIST)
|
||||
panic("%s: pending locks list is too small, bump it\n",
|
||||
panic("%s: pending locks list is too small, "
|
||||
"increase WITNESS_PENDLIST\n",
|
||||
__func__);
|
||||
} else
|
||||
lock->lo_witness = enroll(type, class);
|
||||
@ -1073,7 +1074,8 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
||||
* all spin locks.
|
||||
*/
|
||||
if (td->td_critnest != 0 && !kdb_active)
|
||||
panic("blockable sleep lock (%s) %s @ %s:%d",
|
||||
kassert_panic("acquiring blockable sleep lock with "
|
||||
"spinlock or critical section held (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
|
||||
@ -1117,7 +1119,7 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
||||
fixup_filename(file), line);
|
||||
printf("while exclusively locked from %s:%d\n",
|
||||
fixup_filename(lock1->li_file), lock1->li_line);
|
||||
panic("share->excl");
|
||||
kassert_panic("share->excl");
|
||||
}
|
||||
if ((lock1->li_flags & LI_EXCLUSIVE) == 0 &&
|
||||
(flags & LOP_EXCLUSIVE) != 0) {
|
||||
@ -1126,7 +1128,7 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
|
||||
fixup_filename(file), line);
|
||||
printf("while share locked from %s:%d\n",
|
||||
fixup_filename(lock1->li_file), lock1->li_line);
|
||||
panic("excl->share");
|
||||
kassert_panic("excl->share");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1433,26 +1435,30 @@ witness_upgrade(struct lock_object *lock, int flags, const char *file, int line)
|
||||
class = LOCK_CLASS(lock);
|
||||
if (witness_watch) {
|
||||
if ((lock->lo_flags & LO_UPGRADABLE) == 0)
|
||||
panic("upgrade of non-upgradable lock (%s) %s @ %s:%d",
|
||||
kassert_panic(
|
||||
"upgrade of non-upgradable lock (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if ((class->lc_flags & LC_SLEEPLOCK) == 0)
|
||||
panic("upgrade of non-sleep lock (%s) %s @ %s:%d",
|
||||
kassert_panic(
|
||||
"upgrade of non-sleep lock (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
}
|
||||
instance = find_instance(curthread->td_sleeplocks, lock);
|
||||
if (instance == NULL)
|
||||
panic("upgrade of unlocked lock (%s) %s @ %s:%d",
|
||||
kassert_panic("upgrade of unlocked lock (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if (witness_watch) {
|
||||
if ((instance->li_flags & LI_EXCLUSIVE) != 0)
|
||||
panic("upgrade of exclusive lock (%s) %s @ %s:%d",
|
||||
kassert_panic(
|
||||
"upgrade of exclusive lock (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if ((instance->li_flags & LI_RECURSEMASK) != 0)
|
||||
panic("upgrade of recursed lock (%s) %s r=%d @ %s:%d",
|
||||
kassert_panic(
|
||||
"upgrade of recursed lock (%s) %s r=%d @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
instance->li_flags & LI_RECURSEMASK,
|
||||
fixup_filename(file), line);
|
||||
@ -1473,26 +1479,30 @@ witness_downgrade(struct lock_object *lock, int flags, const char *file,
|
||||
class = LOCK_CLASS(lock);
|
||||
if (witness_watch) {
|
||||
if ((lock->lo_flags & LO_UPGRADABLE) == 0)
|
||||
panic("downgrade of non-upgradable lock (%s) %s @ %s:%d",
|
||||
kassert_panic(
|
||||
"downgrade of non-upgradable lock (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if ((class->lc_flags & LC_SLEEPLOCK) == 0)
|
||||
panic("downgrade of non-sleep lock (%s) %s @ %s:%d",
|
||||
kassert_panic(
|
||||
"downgrade of non-sleep lock (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
}
|
||||
instance = find_instance(curthread->td_sleeplocks, lock);
|
||||
if (instance == NULL)
|
||||
panic("downgrade of unlocked lock (%s) %s @ %s:%d",
|
||||
kassert_panic("downgrade of unlocked lock (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if (witness_watch) {
|
||||
if ((instance->li_flags & LI_EXCLUSIVE) == 0)
|
||||
panic("downgrade of shared lock (%s) %s @ %s:%d",
|
||||
kassert_panic(
|
||||
"downgrade of shared lock (%s) %s @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if ((instance->li_flags & LI_RECURSEMASK) != 0)
|
||||
panic("downgrade of recursed lock (%s) %s r=%d @ %s:%d",
|
||||
kassert_panic(
|
||||
"downgrade of recursed lock (%s) %s r=%d @ %s:%d",
|
||||
class->lc_name, lock->lo_name,
|
||||
instance->li_flags & LI_RECURSEMASK,
|
||||
fixup_filename(file), line);
|
||||
@ -1535,7 +1545,7 @@ witness_unlock(struct lock_object *lock, int flags, const char *file, int line)
|
||||
* eventual register locks and remove them.
|
||||
*/
|
||||
if (witness_watch > 0)
|
||||
panic("lock (%s) %s not locked @ %s:%d", class->lc_name,
|
||||
kassert_panic("lock (%s) %s not locked @ %s:%d", class->lc_name,
|
||||
lock->lo_name, fixup_filename(file), line);
|
||||
else
|
||||
return;
|
||||
@ -1548,7 +1558,7 @@ witness_unlock(struct lock_object *lock, int flags, const char *file, int line)
|
||||
lock->lo_name, fixup_filename(file), line);
|
||||
printf("while exclusively locked from %s:%d\n",
|
||||
fixup_filename(instance->li_file), instance->li_line);
|
||||
panic("excl->ushare");
|
||||
kassert_panic("excl->ushare");
|
||||
}
|
||||
if ((instance->li_flags & LI_EXCLUSIVE) == 0 && witness_watch > 0 &&
|
||||
(flags & LOP_EXCLUSIVE) != 0) {
|
||||
@ -1557,7 +1567,7 @@ witness_unlock(struct lock_object *lock, int flags, const char *file, int line)
|
||||
printf("while share locked from %s:%d\n",
|
||||
fixup_filename(instance->li_file),
|
||||
instance->li_line);
|
||||
panic("share->uexcl");
|
||||
kassert_panic("share->uexcl");
|
||||
}
|
||||
/* If we are recursed, unrecurse. */
|
||||
if ((instance->li_flags & LI_RECURSEMASK) > 0) {
|
||||
@ -1571,7 +1581,7 @@ witness_unlock(struct lock_object *lock, int flags, const char *file, int line)
|
||||
if ((instance->li_flags & LI_NORELEASE) != 0 && witness_watch > 0) {
|
||||
printf("forbidden unlock of (%s) %s @ %s:%d\n", class->lc_name,
|
||||
lock->lo_name, fixup_filename(file), line);
|
||||
panic("lock marked norelease");
|
||||
kassert_panic("lock marked norelease");
|
||||
}
|
||||
|
||||
/* Otherwise, remove this item from the list. */
|
||||
@ -1626,7 +1636,8 @@ witness_thread_exit(struct thread *td)
|
||||
witness_list_lock(&lle->ll_children[i], printf);
|
||||
|
||||
}
|
||||
panic("Thread %p cannot exit while holding sleeplocks\n", td);
|
||||
kassert_panic(
|
||||
"Thread %p cannot exit while holding sleeplocks\n", td);
|
||||
}
|
||||
witness_lock_list_free(lle);
|
||||
}
|
||||
@ -1707,7 +1718,7 @@ witness_warn(int flags, struct lock_object *lock, const char *fmt, ...)
|
||||
} else
|
||||
sched_unpin();
|
||||
if (flags & WARN_PANIC && n)
|
||||
panic("%s", __func__);
|
||||
kassert_panic("%s", __func__);
|
||||
else
|
||||
witness_debugger(n);
|
||||
return (n);
|
||||
@ -1753,7 +1764,7 @@ enroll(const char *description, struct lock_class *lock_class)
|
||||
} else if ((lock_class->lc_flags & LC_SLEEPLOCK))
|
||||
typelist = &w_sleep;
|
||||
else
|
||||
panic("lock class %s is not sleep or spin",
|
||||
kassert_panic("lock class %s is not sleep or spin",
|
||||
lock_class->lc_name);
|
||||
|
||||
mtx_lock_spin(&w_mtx);
|
||||
@ -1784,7 +1795,7 @@ enroll(const char *description, struct lock_class *lock_class)
|
||||
w->w_refcount++;
|
||||
mtx_unlock_spin(&w_mtx);
|
||||
if (lock_class != w->w_class)
|
||||
panic(
|
||||
kassert_panic(
|
||||
"lock (%s) %s does not match earlier (%s) lock",
|
||||
description, lock_class->lc_name,
|
||||
w->w_class->lc_name);
|
||||
@ -1918,7 +1929,8 @@ itismychild(struct witness *parent, struct witness *child)
|
||||
if (!witness_lock_type_equal(parent, child)) {
|
||||
if (witness_cold == 0)
|
||||
mtx_unlock_spin(&w_mtx);
|
||||
panic("%s: parent \"%s\" (%s) and child \"%s\" (%s) are not "
|
||||
kassert_panic(
|
||||
"%s: parent \"%s\" (%s) and child \"%s\" (%s) are not "
|
||||
"the same lock type", __func__, parent->w_name,
|
||||
parent->w_class->lc_name, child->w_name,
|
||||
child->w_class->lc_name);
|
||||
@ -2192,7 +2204,7 @@ witness_save(struct lock_object *lock, const char **filep, int *linep)
|
||||
}
|
||||
instance = find_instance(lock_list, lock);
|
||||
if (instance == NULL)
|
||||
panic("%s: lock (%s) %s not locked", __func__,
|
||||
kassert_panic("%s: lock (%s) %s not locked", __func__,
|
||||
class->lc_name, lock->lo_name);
|
||||
*filep = instance->li_file;
|
||||
*linep = instance->li_line;
|
||||
@ -2225,7 +2237,7 @@ witness_restore(struct lock_object *lock, const char *file, int line)
|
||||
}
|
||||
instance = find_instance(lock_list, lock);
|
||||
if (instance == NULL)
|
||||
panic("%s: lock (%s) %s not locked", __func__,
|
||||
kassert_panic("%s: lock (%s) %s not locked", __func__,
|
||||
class->lc_name, lock->lo_name);
|
||||
lock->lo_witness->w_file = file;
|
||||
lock->lo_witness->w_line = line;
|
||||
@ -2249,13 +2261,13 @@ witness_assert(const struct lock_object *lock, int flags, const char *file,
|
||||
else if ((class->lc_flags & LC_SPINLOCK) != 0)
|
||||
instance = find_instance(PCPU_GET(spinlocks), lock);
|
||||
else {
|
||||
panic("Lock (%s) %s is not sleep or spin!",
|
||||
kassert_panic("Lock (%s) %s is not sleep or spin!",
|
||||
class->lc_name, lock->lo_name);
|
||||
}
|
||||
switch (flags) {
|
||||
case LA_UNLOCKED:
|
||||
if (instance != NULL)
|
||||
panic("Lock (%s) %s locked @ %s:%d.",
|
||||
kassert_panic("Lock (%s) %s locked @ %s:%d.",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
break;
|
||||
@ -2269,34 +2281,36 @@ witness_assert(const struct lock_object *lock, int flags, const char *file,
|
||||
case LA_XLOCKED | LA_RECURSED:
|
||||
case LA_XLOCKED | LA_NOTRECURSED:
|
||||
if (instance == NULL) {
|
||||
panic("Lock (%s) %s not locked @ %s:%d.",
|
||||
kassert_panic("Lock (%s) %s not locked @ %s:%d.",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
break;
|
||||
}
|
||||
if ((flags & LA_XLOCKED) != 0 &&
|
||||
(instance->li_flags & LI_EXCLUSIVE) == 0)
|
||||
panic("Lock (%s) %s not exclusively locked @ %s:%d.",
|
||||
kassert_panic(
|
||||
"Lock (%s) %s not exclusively locked @ %s:%d.",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if ((flags & LA_SLOCKED) != 0 &&
|
||||
(instance->li_flags & LI_EXCLUSIVE) != 0)
|
||||
panic("Lock (%s) %s exclusively locked @ %s:%d.",
|
||||
kassert_panic(
|
||||
"Lock (%s) %s exclusively locked @ %s:%d.",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if ((flags & LA_RECURSED) != 0 &&
|
||||
(instance->li_flags & LI_RECURSEMASK) == 0)
|
||||
panic("Lock (%s) %s not recursed @ %s:%d.",
|
||||
kassert_panic("Lock (%s) %s not recursed @ %s:%d.",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
if ((flags & LA_NOTRECURSED) != 0 &&
|
||||
(instance->li_flags & LI_RECURSEMASK) != 0)
|
||||
panic("Lock (%s) %s recursed @ %s:%d.",
|
||||
kassert_panic("Lock (%s) %s recursed @ %s:%d.",
|
||||
class->lc_name, lock->lo_name,
|
||||
fixup_filename(file), line);
|
||||
break;
|
||||
default:
|
||||
panic("Invalid lock assertion at %s:%d.",
|
||||
kassert_panic("Invalid lock assertion at %s:%d.",
|
||||
fixup_filename(file), line);
|
||||
|
||||
}
|
||||
@ -2322,7 +2336,7 @@ witness_setflag(struct lock_object *lock, int flag, int set)
|
||||
}
|
||||
instance = find_instance(lock_list, lock);
|
||||
if (instance == NULL)
|
||||
panic("%s: lock (%s) %s not locked", __func__,
|
||||
kassert_panic("%s: lock (%s) %s not locked", __func__,
|
||||
class->lc_name, lock->lo_name);
|
||||
|
||||
if (set)
|
||||
|
@ -72,9 +72,11 @@ extern int vm_guest; /* Running as virtual machine guest? */
|
||||
*/
|
||||
enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN };
|
||||
|
||||
#ifdef INVARIANTS /* The option is always available */
|
||||
#if defined(WITNESS) || defined(INVARIANTS)
|
||||
void kassert_panic(const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
#ifdef INVARIANTS /* The option is always available */
|
||||
#define KASSERT(exp,msg) do { \
|
||||
if (__predict_false(!(exp))) \
|
||||
kassert_panic msg; \
|
||||
|
Loading…
Reference in New Issue
Block a user