- Improve some witness_watch operability in code which does perform both
lock tracking and checks, doing just the former ones. - Fix a bug where sysctl utility was printing crazy values when setting a new value for debug.witness.watch [0] [0] Reported by: yongari
This commit is contained in:
parent
74bb9e3ad5
commit
988d28340a
@ -980,7 +980,7 @@ int
|
|||||||
witness_defineorder(struct lock_object *lock1, struct lock_object *lock2)
|
witness_defineorder(struct lock_object *lock1, struct lock_object *lock2)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (witness_watch < 1 || panicstr != NULL)
|
if (witness_watch == -1 || panicstr != NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* Require locks that witness knows about. */
|
/* Require locks that witness knows about. */
|
||||||
@ -995,7 +995,8 @@ witness_defineorder(struct lock_object *lock1, struct lock_object *lock2)
|
|||||||
* If we already have either an explicit or implied lock order that
|
* If we already have either an explicit or implied lock order that
|
||||||
* is the other way around, then return an error.
|
* is the other way around, then return an error.
|
||||||
*/
|
*/
|
||||||
if (isitmydescendant(lock2->lo_witness, lock1->lo_witness)) {
|
if (witness_watch &&
|
||||||
|
isitmydescendant(lock2->lo_witness, lock1->lo_witness)) {
|
||||||
mtx_unlock_spin(&w_mtx);
|
mtx_unlock_spin(&w_mtx);
|
||||||
return (EDOOFUS);
|
return (EDOOFUS);
|
||||||
}
|
}
|
||||||
@ -1356,27 +1357,31 @@ witness_upgrade(struct lock_object *lock, int flags, const char *file, int line)
|
|||||||
struct lock_class *class;
|
struct lock_class *class;
|
||||||
|
|
||||||
KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
|
KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
|
||||||
if (lock->lo_witness == NULL || witness_watch < 1 || panicstr != NULL)
|
if (lock->lo_witness == NULL || witness_watch == -1 || panicstr != NULL)
|
||||||
return;
|
return;
|
||||||
class = LOCK_CLASS(lock);
|
class = LOCK_CLASS(lock);
|
||||||
file = fixup_filename(file);
|
file = fixup_filename(file);
|
||||||
if ((lock->lo_flags & LO_UPGRADABLE) == 0)
|
if (witness_watch) {
|
||||||
panic("upgrade of non-upgradable lock (%s) %s @ %s:%d",
|
if ((lock->lo_flags & LO_UPGRADABLE) == 0)
|
||||||
class->lc_name, lock->lo_name, file, line);
|
panic("upgrade of non-upgradable lock (%s) %s @ %s:%d",
|
||||||
if ((class->lc_flags & LC_SLEEPLOCK) == 0)
|
class->lc_name, lock->lo_name, file, line);
|
||||||
panic("upgrade of non-sleep lock (%s) %s @ %s:%d",
|
if ((class->lc_flags & LC_SLEEPLOCK) == 0)
|
||||||
class->lc_name, lock->lo_name, file, line);
|
panic("upgrade of non-sleep lock (%s) %s @ %s:%d",
|
||||||
|
class->lc_name, lock->lo_name, file, line);
|
||||||
|
}
|
||||||
instance = find_instance(curthread->td_sleeplocks, lock);
|
instance = find_instance(curthread->td_sleeplocks, lock);
|
||||||
if (instance == NULL)
|
if (instance == NULL)
|
||||||
panic("upgrade of unlocked lock (%s) %s @ %s:%d",
|
panic("upgrade of unlocked lock (%s) %s @ %s:%d",
|
||||||
class->lc_name, lock->lo_name, file, line);
|
class->lc_name, lock->lo_name, file, line);
|
||||||
if ((instance->li_flags & LI_EXCLUSIVE) != 0)
|
if (witness_watch) {
|
||||||
panic("upgrade of exclusive lock (%s) %s @ %s:%d",
|
if ((instance->li_flags & LI_EXCLUSIVE) != 0)
|
||||||
class->lc_name, lock->lo_name, file, line);
|
panic("upgrade of exclusive lock (%s) %s @ %s:%d",
|
||||||
if ((instance->li_flags & LI_RECURSEMASK) != 0)
|
class->lc_name, lock->lo_name, file, line);
|
||||||
panic("upgrade of recursed lock (%s) %s r=%d @ %s:%d",
|
if ((instance->li_flags & LI_RECURSEMASK) != 0)
|
||||||
class->lc_name, lock->lo_name,
|
panic("upgrade of recursed lock (%s) %s r=%d @ %s:%d",
|
||||||
instance->li_flags & LI_RECURSEMASK, file, line);
|
class->lc_name, lock->lo_name,
|
||||||
|
instance->li_flags & LI_RECURSEMASK, file, line);
|
||||||
|
}
|
||||||
instance->li_flags |= LI_EXCLUSIVE;
|
instance->li_flags |= LI_EXCLUSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1388,27 +1393,31 @@ witness_downgrade(struct lock_object *lock, int flags, const char *file,
|
|||||||
struct lock_class *class;
|
struct lock_class *class;
|
||||||
|
|
||||||
KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
|
KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
|
||||||
if (lock->lo_witness == NULL || witness_watch < 1 || panicstr != NULL)
|
if (lock->lo_witness == NULL || witness_watch == -1 || panicstr != NULL)
|
||||||
return;
|
return;
|
||||||
class = LOCK_CLASS(lock);
|
class = LOCK_CLASS(lock);
|
||||||
file = fixup_filename(file);
|
file = fixup_filename(file);
|
||||||
if ((lock->lo_flags & LO_UPGRADABLE) == 0)
|
if (witness_watch) {
|
||||||
|
if ((lock->lo_flags & LO_UPGRADABLE) == 0)
|
||||||
panic("downgrade of non-upgradable lock (%s) %s @ %s:%d",
|
panic("downgrade of non-upgradable lock (%s) %s @ %s:%d",
|
||||||
class->lc_name, lock->lo_name, file, line);
|
class->lc_name, lock->lo_name, file, line);
|
||||||
if ((class->lc_flags & LC_SLEEPLOCK) == 0)
|
if ((class->lc_flags & LC_SLEEPLOCK) == 0)
|
||||||
panic("downgrade of non-sleep lock (%s) %s @ %s:%d",
|
panic("downgrade of non-sleep lock (%s) %s @ %s:%d",
|
||||||
class->lc_name, lock->lo_name, file, line);
|
class->lc_name, lock->lo_name, file, line);
|
||||||
|
}
|
||||||
instance = find_instance(curthread->td_sleeplocks, lock);
|
instance = find_instance(curthread->td_sleeplocks, lock);
|
||||||
if (instance == NULL)
|
if (instance == NULL)
|
||||||
panic("downgrade of unlocked lock (%s) %s @ %s:%d",
|
panic("downgrade of unlocked lock (%s) %s @ %s:%d",
|
||||||
class->lc_name, lock->lo_name, file, line);
|
class->lc_name, lock->lo_name, file, line);
|
||||||
if ((instance->li_flags & LI_EXCLUSIVE) == 0)
|
if (witness_watch) {
|
||||||
panic("downgrade of shared lock (%s) %s @ %s:%d",
|
if ((instance->li_flags & LI_EXCLUSIVE) == 0)
|
||||||
class->lc_name, lock->lo_name, file, line);
|
panic("downgrade of shared lock (%s) %s @ %s:%d",
|
||||||
if ((instance->li_flags & LI_RECURSEMASK) != 0)
|
class->lc_name, lock->lo_name, file, line);
|
||||||
panic("downgrade of recursed lock (%s) %s r=%d @ %s:%d",
|
if ((instance->li_flags & LI_RECURSEMASK) != 0)
|
||||||
class->lc_name, lock->lo_name,
|
panic("downgrade of recursed lock (%s) %s r=%d @ %s:%d",
|
||||||
instance->li_flags & LI_RECURSEMASK, file, line);
|
class->lc_name, lock->lo_name,
|
||||||
|
instance->li_flags & LI_RECURSEMASK, file, line);
|
||||||
|
}
|
||||||
instance->li_flags &= ~LI_EXCLUSIVE;
|
instance->li_flags &= ~LI_EXCLUSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1443,9 +1452,9 @@ witness_unlock(struct lock_object *lock, int flags, const char *file, int line)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* When disabling WITNESS through witness_watch we could end up in
|
* When disabling WITNESS through witness_watch we could end up in
|
||||||
* having registered locks in the locks list queue.
|
* having registered locks in the td_sleeplocks queue.
|
||||||
* We have to make sure we flush these queues, so just search for
|
* We have to make sure we flush these queues, so just search for
|
||||||
* eventual registered locks and remove them.
|
* eventual register locks and remove them.
|
||||||
*/
|
*/
|
||||||
if (witness_watch > 0)
|
if (witness_watch > 0)
|
||||||
panic("lock (%s) %s not locked @ %s:%d", class->lc_name,
|
panic("lock (%s) %s not locked @ %s:%d", class->lc_name,
|
||||||
@ -1630,7 +1639,7 @@ enroll(const char *description, struct lock_class *lock_class)
|
|||||||
|
|
||||||
MPASS(description != NULL);
|
MPASS(description != NULL);
|
||||||
|
|
||||||
if (witness_watch < 1 || panicstr != NULL)
|
if (witness_watch == -1 || panicstr != NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if ((lock_class->lc_flags & LC_SPINLOCK)) {
|
if ((lock_class->lc_flags & LC_SPINLOCK)) {
|
||||||
if (witness_skipspin)
|
if (witness_skipspin)
|
||||||
@ -1897,7 +1906,7 @@ witness_get(void)
|
|||||||
if (witness_cold == 0)
|
if (witness_cold == 0)
|
||||||
mtx_assert(&w_mtx, MA_OWNED);
|
mtx_assert(&w_mtx, MA_OWNED);
|
||||||
|
|
||||||
if (witness_watch < 1) {
|
if (witness_watch == -1) {
|
||||||
mtx_unlock_spin(&w_mtx);
|
mtx_unlock_spin(&w_mtx);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -2055,7 +2064,7 @@ witness_save(struct lock_object *lock, const char **filep, int *linep)
|
|||||||
struct lock_class *class;
|
struct lock_class *class;
|
||||||
|
|
||||||
KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
|
KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
|
||||||
if (lock->lo_witness == NULL || witness_watch < 1 || panicstr != NULL)
|
if (lock->lo_witness == NULL || witness_watch == -1 || panicstr != NULL)
|
||||||
return;
|
return;
|
||||||
class = LOCK_CLASS(lock);
|
class = LOCK_CLASS(lock);
|
||||||
if (class->lc_flags & LC_SLEEPLOCK)
|
if (class->lc_flags & LC_SLEEPLOCK)
|
||||||
@ -2081,7 +2090,7 @@ witness_restore(struct lock_object *lock, const char *file, int line)
|
|||||||
struct lock_class *class;
|
struct lock_class *class;
|
||||||
|
|
||||||
KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
|
KASSERT(witness_cold == 0, ("%s: witness_cold", __func__));
|
||||||
if (lock->lo_witness == NULL || witness_watch < 1 || panicstr != NULL)
|
if (lock->lo_witness == NULL || witness_watch == -1 || panicstr != NULL)
|
||||||
return;
|
return;
|
||||||
class = LOCK_CLASS(lock);
|
class = LOCK_CLASS(lock);
|
||||||
if (class->lc_flags & LC_SLEEPLOCK)
|
if (class->lc_flags & LC_SLEEPLOCK)
|
||||||
@ -2445,6 +2454,7 @@ sysctl_debug_witness_watch(SYSCTL_HANDLER_ARGS)
|
|||||||
{
|
{
|
||||||
int error, value;
|
int error, value;
|
||||||
|
|
||||||
|
value = witness_watch;
|
||||||
error = sysctl_handle_int(oidp, &value, 0, req);
|
error = sysctl_handle_int(oidp, &value, 0, req);
|
||||||
if (error != 0 || req->newptr == NULL)
|
if (error != 0 || req->newptr == NULL)
|
||||||
return (error);
|
return (error);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user