summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-05-08 21:51:37 +0000
committerjhb <jhb@FreeBSD.org>2007-05-08 21:51:37 +0000
commit7b6b99abf6dac45f71e174a2cebfc5aa4491c92e (patch)
tree666b5595ce1dc5855c3c502c770842207fe32fdc /sys/kern
parent86f8e9262ca3de6030e897ec1138a07a24a33b44 (diff)
downloadFreeBSD-src-7b6b99abf6dac45f71e174a2cebfc5aa4491c92e.zip
FreeBSD-src-7b6b99abf6dac45f71e174a2cebfc5aa4491c92e.tar.gz
Add destroyed cookie values for sx locks and rwlocks as well as extra
KASSERTs so that any lock operations on a destroyed lock will panic or hang.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_rwlock.c18
-rw-r--r--sys/kern/kern_sx.c22
2 files changed, 38 insertions, 2 deletions
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index 3180a8b..1a3a11f 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -133,6 +133,7 @@ rw_destroy(struct rwlock *rw)
{
KASSERT(rw->rw_lock == RW_UNLOCKED, ("rw lock not unlocked"));
+ rw->rw_lock = RW_DESTROYED;
lock_profile_object_destroy(&rw->lock_object);
lock_destroy(&rw->lock_object);
}
@@ -157,6 +158,8 @@ _rw_wlock(struct rwlock *rw, const char *file, int line)
{
MPASS(curthread != NULL);
+ KASSERT(rw->rw_lock != RW_DESTROYED,
+ ("rw_wlock() of destroyed rwlock @ %s:%d", file, line));
KASSERT(rw_wowner(rw) != curthread,
("%s (%s): wlock already held @ %s:%d", __func__,
rw->lock_object.lo_name, file, line));
@@ -173,6 +176,8 @@ _rw_wunlock(struct rwlock *rw, const char *file, int line)
{
MPASS(curthread != NULL);
+ KASSERT(rw->rw_lock != RW_DESTROYED,
+ ("rw_wunlock() of destroyed rwlock @ %s:%d", file, line));
_rw_assert(rw, RA_WLOCKED, file, line);
curthread->td_locks--;
WITNESS_UNLOCK(&rw->lock_object, LOP_EXCLUSIVE, file, line);
@@ -191,6 +196,8 @@ _rw_rlock(struct rwlock *rw, const char *file, int line)
int contested = 0;
uintptr_t x;
+ KASSERT(rw->rw_lock != RW_DESTROYED,
+ ("rw_rlock() of destroyed rwlock @ %s:%d", file, line));
KASSERT(rw_wowner(rw) != curthread,
("%s (%s): wlock already held @ %s:%d", __func__,
rw->lock_object.lo_name, file, line));
@@ -332,6 +339,8 @@ _rw_runlock(struct rwlock *rw, const char *file, int line)
struct turnstile *ts;
uintptr_t x;
+ KASSERT(rw->rw_lock != RW_DESTROYED,
+ ("rw_runlock() of destroyed rwlock @ %s:%d", file, line));
_rw_assert(rw, RA_RLOCKED, file, line);
curthread->td_locks--;
WITNESS_UNLOCK(&rw->lock_object, 0, file, line);
@@ -657,6 +666,8 @@ _rw_try_upgrade(struct rwlock *rw, const char *file, int line)
uintptr_t v, tid;
int success;
+ KASSERT(rw->rw_lock != RW_DESTROYED,
+ ("rw_try_upgrade() of destroyed rwlock @ %s:%d", file, line));
_rw_assert(rw, RA_RLOCKED, file, line);
/*
@@ -716,6 +727,8 @@ _rw_downgrade(struct rwlock *rw, const char *file, int line)
struct turnstile *ts;
uintptr_t tid, v;
+ KASSERT(rw->rw_lock != RW_DESTROYED,
+ ("rw_downgrade() of destroyed rwlock @ %s:%d", file, line));
_rw_assert(rw, RA_WLOCKED, file, line);
WITNESS_DOWNGRADE(&rw->lock_object, 0, file, line);
@@ -851,7 +864,10 @@ db_show_rwlock(struct lock_object *lock)
db_printf(" state: ");
if (rw->rw_lock == RW_UNLOCKED)
db_printf("UNLOCKED\n");
- else if (rw->rw_lock & RW_LOCK_READ)
+ else if (rw->rw_lock == RW_DESTROYED) {
+ db_printf("DESTROYED\n");
+ return;
+ } else if (rw->rw_lock & RW_LOCK_READ)
db_printf("RLOCK: %ju locks\n",
(uintmax_t)(RW_READERS(rw->rw_lock)));
else {
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index bbb62d0..0204e6a 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -193,6 +193,7 @@ sx_destroy(struct sx *sx)
KASSERT(sx->sx_lock == SX_LOCK_UNLOCKED, ("sx lock still held"));
KASSERT(sx->sx_recurse == 0, ("sx lock still recursed"));
+ sx->sx_lock = SX_LOCK_DESTROYED;
lock_profile_object_destroy(&sx->lock_object);
lock_destroy(&sx->lock_object);
}
@@ -202,6 +203,8 @@ _sx_slock(struct sx *sx, const char *file, int line)
{
MPASS(curthread != NULL);
+ KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
+ ("sx_slock() of destroyed sx @ %s:%d", file, line));
WITNESS_CHECKORDER(&sx->lock_object, LOP_NEWORDER, file, line);
__sx_slock(sx, file, line);
LOCK_LOG_LOCK("SLOCK", &sx->lock_object, 0, 0, file, line);
@@ -215,6 +218,8 @@ _sx_try_slock(struct sx *sx, const char *file, int line)
uintptr_t x;
x = sx->sx_lock;
+ KASSERT(x != SX_LOCK_DESTROYED,
+ ("sx_try_slock() of destroyed sx @ %s:%d", file, line));
if ((x & SX_LOCK_SHARED) && atomic_cmpset_acq_ptr(&sx->sx_lock, x,
x + SX_ONE_SHARER)) {
LOCK_LOG_TRY("SLOCK", &sx->lock_object, 0, 1, file, line);
@@ -232,6 +237,8 @@ _sx_xlock(struct sx *sx, const char *file, int line)
{
MPASS(curthread != NULL);
+ KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
+ ("sx_xlock() of destroyed sx @ %s:%d", file, line));
WITNESS_CHECKORDER(&sx->lock_object, LOP_NEWORDER | LOP_EXCLUSIVE, file,
line);
__sx_xlock(sx, curthread, file, line);
@@ -246,6 +253,8 @@ _sx_try_xlock(struct sx *sx, const char *file, int line)
int rval;
MPASS(curthread != NULL);
+ KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
+ ("sx_try_xlock() of destroyed sx @ %s:%d", file, line));
if (sx_xlocked(sx)) {
sx->sx_recurse++;
@@ -269,6 +278,8 @@ _sx_sunlock(struct sx *sx, const char *file, int line)
{
MPASS(curthread != NULL);
+ KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
+ ("sx_sunlock() of destroyed sx @ %s:%d", file, line));
_sx_assert(sx, SX_SLOCKED, file, line);
curthread->td_locks--;
WITNESS_UNLOCK(&sx->lock_object, 0, file, line);
@@ -283,6 +294,8 @@ _sx_xunlock(struct sx *sx, const char *file, int line)
{
MPASS(curthread != NULL);
+ KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
+ ("sx_xunlock() of destroyed sx @ %s:%d", file, line));
_sx_assert(sx, SX_XLOCKED, file, line);
curthread->td_locks--;
WITNESS_UNLOCK(&sx->lock_object, LOP_EXCLUSIVE, file, line);
@@ -304,6 +317,8 @@ _sx_try_upgrade(struct sx *sx, const char *file, int line)
uintptr_t x;
int success;
+ KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
+ ("sx_try_upgrade() of destroyed sx @ %s:%d", file, line));
_sx_assert(sx, SX_SLOCKED, file, line);
/*
@@ -329,6 +344,8 @@ _sx_downgrade(struct sx *sx, const char *file, int line)
{
uintptr_t x;
+ KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
+ ("sx_downgrade() of destroyed sx @ %s:%d", file, line));
_sx_assert(sx, SX_XLOCKED | SX_NOTRECURSED, file, line);
#ifndef INVARIANTS
if (sx_recursed(sx))
@@ -916,7 +933,10 @@ db_show_sx(struct lock_object *lock)
db_printf(" state: ");
if (sx->sx_lock == SX_LOCK_UNLOCKED)
db_printf("UNLOCKED\n");
- else if (sx->sx_lock & SX_LOCK_SHARED)
+ else if (sx->sx_lock == SX_LOCK_DESTROYED) {
+ db_printf("DESTROYED\n");
+ return;
+ } else if (sx->sx_lock & SX_LOCK_SHARED)
db_printf("SLOCK: %ju\n", (uintmax_t)SX_SHARERS(sx->sx_lock));
else {
td = sx_xholder(sx);
OpenPOWER on IntegriCloud