Fix INVARIANTS support

This commit is contained in:
Sebastian Huber 2017-05-18 09:35:46 +02:00
parent 5be4f06fa8
commit 62c8ca0ead
10 changed files with 138 additions and 195 deletions

View File

@ -2108,8 +2108,10 @@ static void
kqueue_destroy(struct kqueue *kq)
{
#ifndef __rtems__
KASSERT(kq->kq_fdp == NULL,
("kqueue still attached to a file descriptor"));
#endif /* __rtems__ */
seldrain(&kq->kq_sel);
knlist_destroy(&kq->kq_sel.si_note);
mtx_destroy(&kq->kq_lock);

View File

@ -84,8 +84,10 @@ lock_init(struct lock_object *lock, struct lock_class *class, const char *name,
int i;
/* Check for double-init and zero object. */
#ifndef __rtems__
KASSERT(flags & LO_NEW || !lock_initialized(lock),
("lock \"%s\" %p already initialized", name, lock));
#endif /* __rtems__ */
/* Look up lock class to find its index. */
for (i = 0; i < LOCK_CLASS_MAX; i++)

View File

@ -112,6 +112,7 @@ void _rm_assert(const struct rmlock *rm, int what, const char *file,
#define rm_rlock(rm, tracker) do { (void)tracker; rw_rlock(rm); } while (0)
#define rm_runlock(rm, tracker) do { (void)tracker; rw_runlock(rm); } while (0)
#define rm_sleep rw_sleep
#define _rm_assert _rw_assert
#endif /* __rtems__ */

View File

@ -164,6 +164,10 @@ int _rw_try_rlock(struct rwlock *rw, const char *file, int line);
void _rw_runlock(struct rwlock *rw, const char *file, int line);
int _rw_try_upgrade(struct rwlock *rw, const char *file, int line);
void _rw_downgrade(struct rwlock *rw, const char *file, int line);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
void _rw_assert(const struct rwlock *rw, int what, const char *file,
int line);
#endif
#endif /* __rtems__ */
#ifndef __rtems__

View File

@ -105,7 +105,11 @@ enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV,
VM_GUEST_VMWARE, VM_GUEST_KVM, VM_LAST };
#if defined(WITNESS) || defined(INVARIANT_SUPPORT)
#ifndef __rtems__
void kassert_panic(const char *fmt, ...) __printflike(1, 2);
#else /* __rtems__ */
#define kassert_panic panic
#endif /* __rtems__ */
#endif
#ifdef INVARIANTS /* The option is always available */

View File

@ -2204,8 +2204,10 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags)
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"uma_zalloc_arg: zone \"%s\"", zone->uz_name);
}
#ifndef __rtems__
KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
("uma_zalloc_arg: called with spinlock or critical section held"));
#endif /* __rtems__ */
#ifdef DEBUG_MEMGUARD
if (memguard_cmp_zone(zone)) {
@ -2742,8 +2744,10 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
CTR2(KTR_UMA, "uma_zfree_arg thread %x zone %s", curthread,
zone->uz_name);
#ifndef __rtems__
KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
("uma_zfree_arg: called with spinlock or critical section held"));
#endif /* __rtems__ */
/* uma_zfree(..., NULL) does nothing, to match free(9). */
if (item == NULL)

View File

@ -209,18 +209,32 @@ rtems_bsd_mutex_unlock(rtems_bsd_mutex *m)
}
}
static inline int
rtems_bsd_mutex_owned(rtems_bsd_mutex *m)
static inline Thread_Control *
rtems_bsd_mutex_owner(const rtems_bsd_mutex *m)
{
return (m->queue.Queue.owner == _Thread_Get_executing());
return (m->queue.Queue.owner);
}
static inline int
rtems_bsd_mutex_recursed(rtems_bsd_mutex *m)
rtems_bsd_mutex_owned(const rtems_bsd_mutex *m)
{
return (m->nest_level);
return (rtems_bsd_mutex_owner(m) == _Thread_Get_executing());
}
static inline int
rtems_bsd_mutex_recursed(const rtems_bsd_mutex *m)
{
return (m->nest_level != 0);
}
static inline const char *
rtems_bsd_mutex_name(const rtems_bsd_mutex *m)
{
return (m->queue.Queue.name);
}
static inline void

View File

@ -164,33 +164,30 @@ _mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
void
_mtx_assert(struct mtx *m, int what, const char *file, int line)
{
const char *name = rtems_bsd_mutex_name(&m->mutex);
if (panicstr != NULL || dumping)
return;
switch (what) {
case MA_OWNED:
case MA_OWNED | MA_RECURSED:
case MA_OWNED | MA_NOTRECURSED:
if (!mtx_owned(m))
panic("mutex %s not owned at %s:%d",
m->lock_object.lo_name, file, line);
if (mtx_recursed(m)) {
if ((what & MA_NOTRECURSED) != 0)
panic("mutex %s recursed at %s:%d",
m->lock_object.lo_name, file, line);
} else if ((what & MA_RECURSED) != 0) {
panic("mutex %s unrecursed at %s:%d",
m->lock_object.lo_name, file, line);
}
break;
case MA_NOTOWNED:
if (mtx_owned(m))
panic("mutex %s owned at %s:%d",
m->lock_object.lo_name, file, line);
break;
default:
panic("unknown mtx_assert at %s:%d", file, line);
}
switch (what) {
case MA_OWNED:
case MA_OWNED | MA_RECURSED:
case MA_OWNED | MA_NOTRECURSED:
if (!mtx_owned(m))
panic("mutex %s not owned at %s:%d", name, file, line);
if (mtx_recursed(m)) {
if ((what & MA_NOTRECURSED) != 0)
panic("mutex %s recursed at %s:%d", name, file,
line);
} else if ((what & MA_RECURSED) != 0) {
panic("mutex %s unrecursed at %s:%d", name, file,
line);
}
break;
case MA_NOTOWNED:
if (mtx_owned(m))
panic("mutex %s owned at %s:%d", name, file, line);
break;
default:
panic("unknown mtx_assert at %s:%d", file, line);
}
}
#endif

View File

@ -79,9 +79,9 @@ struct lock_class lock_class_rw = {
#endif
};
#define rw_wowner(rw) ((rw)->mutex.owner)
#define rw_wowner(rw) rtems_bsd_mutex_owner(&(rw)->mutex)
#define rw_recursed(rw) ((rw)->mutex.nest_level != 0)
#define rw_recursed(rw) rtems_bsd_mutex_recursed(&(rw)->mutex)
void
assert_rw(struct lock_object *lock, int what)
@ -207,87 +207,53 @@ _rw_downgrade(struct rwlock *rw, const char *file, int line)
}
#ifdef INVARIANT_SUPPORT
#ifndef INVARIANTS
#undef _rw_assert
#endif
/*
* In the non-WITNESS case, rw_assert() can only detect that at least
* *some* thread owns an rlock, but it cannot guarantee that *this*
* thread owns an rlock.
*/
void
_rw_assert(struct rwlock *rw, int what, const char *file, int line)
_rw_assert(const struct rwlock *rw, int what, const char *file, int line)
{
const char *name = rtems_bsd_mutex_name(&rw->mutex);
if (panicstr != NULL)
return;
switch (what) {
case RA_LOCKED:
case RA_LOCKED | RA_RECURSED:
case RA_LOCKED | RA_NOTRECURSED:
case RA_RLOCKED:
#ifndef __rtems__
switch (what) {
case RA_LOCKED:
case RA_LOCKED | RA_RECURSED:
case RA_LOCKED | RA_NOTRECURSED:
case RA_RLOCKED:
case RA_RLOCKED | RA_RECURSED:
case RA_RLOCKED | RA_NOTRECURSED:
case RA_WLOCKED:
case RA_WLOCKED | RA_RECURSED:
case RA_WLOCKED | RA_NOTRECURSED:
if (rw_wowner(rw) != _Thread_Get_executing())
panic("Lock %s not exclusively locked @ %s:%d\n",
name, file, line);
if (rw_recursed(rw)) {
if (what & RA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n", name, file,
line);
} else if (what & RA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n", name, file,
line);
break;
case RA_UNLOCKED:
#ifdef WITNESS
witness_assert(&rw->lock_object, what, file, line);
witness_assert(&rw->lock_object, what, file, line);
#else
/*
* If some other thread has a write lock or we have one
* and are asserting a read lock, fail. Also, if no one
* has a lock at all, fail.
*/
if (rw->rw_lock == RW_UNLOCKED ||
(!(rw->rw_lock & RW_LOCK_READ) && (what == RA_RLOCKED ||
rw_wowner(rw) != curthread)))
panic("Lock %s not %slocked @ %s:%d\n",
rw->lock_object.lo_name, (what == RA_RLOCKED) ?
"read " : "", file, line);
if (!(rw->rw_lock & RW_LOCK_READ)) {
if (rw_recursed(rw)) {
if (what & RA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n",
rw->lock_object.lo_name, file,
line);
} else if (what & RA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n",
rw->lock_object.lo_name, file, line);
}
/*
* If we hold a write lock fail. We can't reliably check
* to see if we hold a read lock or not.
*/
if (rw_wowner(rw) == _Thread_Get_executing())
panic("Lock %s exclusively locked @ %s:%d\n", name,
file, line);
#endif
break;
#else /* __rtems__ */
/* FALLTHROUGH */
#endif /* __rtems__ */
case RA_WLOCKED:
case RA_WLOCKED | RA_RECURSED:
case RA_WLOCKED | RA_NOTRECURSED:
if (rw_wowner(rw) != _Thread_Get_executing())
panic("Lock %s not exclusively locked @ %s:%d\n",
rw->lock_object.lo_name, file, line);
if (rw_recursed(rw)) {
if (what & RA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n",
rw->lock_object.lo_name, file, line);
} else if (what & RA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n",
rw->lock_object.lo_name, file, line);
break;
case RA_UNLOCKED:
#ifdef WITNESS
witness_assert(&rw->lock_object, what, file, line);
#else
/*
* If we hold a write lock fail. We can't reliably check
* to see if we hold a read lock or not.
*/
if (rw_wowner(rw) == _Thread_Get_executing())
panic("Lock %s exclusively locked @ %s:%d\n",
rw->lock_object.lo_name, file, line);
#endif
break;
default:
panic("Unknown rw lock assertion: %d @ %s:%d", what, file,
line);
}
break;
default:
panic("Unknown rw lock assertion: %d @ %s:%d", what, file,
line);
}
}
#endif /* INVARIANT_SUPPORT */

View File

@ -47,10 +47,6 @@
#include <sys/lock.h>
#include <sys/sx.h>
#ifndef INVARIANTS
#define _sx_assert(sx, what, file, line)
#endif
static void assert_sx(struct lock_object *lock, int what);
static void lock_sx(struct lock_object *lock, int how);
#ifdef KDTRACE_HOOKS
@ -72,9 +68,9 @@ struct lock_class lock_class_sx = {
#endif
};
#define sx_xholder(sx) ((sx)->mutex.owner)
#define sx_xholder(sx) rtems_bsd_mutex_owner(&(sx)->mutex)
#define sx_recursed(sx) ((sx)->mutex.nest_level != 0)
#define sx_recursed(sx) rtems_bsd_mutex_recursed(&(sx)->mutex)
void
assert_sx(struct lock_object *lock, int what)
@ -170,102 +166,55 @@ sx_downgrade_(struct sx *sx, const char *file, int line)
}
#ifdef INVARIANT_SUPPORT
#ifndef INVARIANTS
#undef _sx_assert
#endif
/*
* In the non-WITNESS case, sx_assert() can only detect that at least
* *some* thread owns an slock, but it cannot guarantee that *this*
* thread owns an slock.
*/
void
_sx_assert(struct sx *sx, int what, const char *file, int line)
_sx_assert(const struct sx *sx, int what, const char *file, int line)
{
#ifndef __rtems__
#ifndef WITNESS
int slocked = 0;
#endif
#endif /* __rtems__ */
const char *name = rtems_bsd_mutex_name(&sx->mutex);
if (panicstr != NULL)
return;
switch (what) {
case SA_SLOCKED:
case SA_SLOCKED | SA_NOTRECURSED:
case SA_SLOCKED | SA_RECURSED:
#ifndef __rtems__
#ifndef WITNESS
slocked = 1;
/* FALLTHROUGH */
#endif
#endif /* __rtems__ */
case SA_LOCKED:
case SA_LOCKED | SA_NOTRECURSED:
case SA_LOCKED | SA_RECURSED:
#ifndef __rtems__
switch (what) {
case SA_SLOCKED:
case SA_SLOCKED | SA_NOTRECURSED:
case SA_SLOCKED | SA_RECURSED:
case SA_LOCKED:
case SA_LOCKED | SA_NOTRECURSED:
case SA_LOCKED | SA_RECURSED:
case SA_XLOCKED:
case SA_XLOCKED | SA_NOTRECURSED:
case SA_XLOCKED | SA_RECURSED:
if (sx_xholder(sx) != _Thread_Get_executing())
panic("Lock %s not exclusively locked @ %s:%d\n", name,
file, line);
if (sx_recursed(sx)) {
if (what & SA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n", name, file,
line);
} else if (what & SA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n", name, file,
line);
break;
case SA_UNLOCKED:
#ifdef WITNESS
witness_assert(&sx->lock_object, what, file, line);
witness_assert(&sx->lock_object, what, file, line);
#else
/*
* If some other thread has an exclusive lock or we
* have one and are asserting a shared lock, fail.
* Also, if no one has a lock at all, fail.
*/
if (sx->sx_lock == SX_LOCK_UNLOCKED ||
(!(sx->sx_lock & SX_LOCK_SHARED) && (slocked ||
sx_xholder(sx) != curthread)))
panic("Lock %s not %slocked @ %s:%d\n",
sx->lock_object.lo_name, slocked ? "share " : "",
file, line);
if (!(sx->sx_lock & SX_LOCK_SHARED)) {
if (sx_recursed(sx)) {
if (what & SA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n",
sx->lock_object.lo_name, file,
line);
} else if (what & SA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n",
sx->lock_object.lo_name, file, line);
}
/*
* If we hold an exclusve lock fail. We can't
* reliably check to see if we hold a shared lock or
* not.
*/
if (sx_xholder(sx) == _Thread_Get_executing())
panic("Lock %s exclusively locked @ %s:%d\n", name,
file, line);
#endif
break;
#else /* __rtems__ */
/* FALLTHROUGH */
#endif /* __rtems__ */
case SA_XLOCKED:
case SA_XLOCKED | SA_NOTRECURSED:
case SA_XLOCKED | SA_RECURSED:
if (sx_xholder(sx) != _Thread_Get_executing())
panic("Lock %s not exclusively locked @ %s:%d\n",
sx->lock_object.lo_name, file, line);
if (sx_recursed(sx)) {
if (what & SA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n",
sx->lock_object.lo_name, file, line);
} else if (what & SA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n",
sx->lock_object.lo_name, file, line);
break;
case SA_UNLOCKED:
#ifdef WITNESS
witness_assert(&sx->lock_object, what, file, line);
#else
/*
* If we hold an exclusve lock fail. We can't
* reliably check to see if we hold a shared lock or
* not.
*/
if (sx_xholder(sx) == _Thread_Get_executing())
panic("Lock %s exclusively locked @ %s:%d\n",
sx->lock_object.lo_name, file, line);
#endif
break;
default:
panic("Unknown sx lock assertion: %d @ %s:%d", what, file,
line);
}
break;
default:
panic("Unknown sx lock assertion: %d @ %s:%d", what, file,
line);
}
}
#endif /* INVARIANT_SUPPORT */