From 704cb42f2a109f5b8f37055df38ae3779dffe438 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 19 Jun 2017 21:09:50 +0000 Subject: [PATCH] Fix the !TD_IS_IDLETHREAD(curthread) locking assertions. Most of the lock slowpaths assert that the calling thread isn't an idle thread. However, this may not be true if the system has panicked, and in some cases the assertion appears before a SCHEDULER_STOPPED() check. MFC after: 3 days Sponsored by: Dell EMC Isilon --- sys/kern/kern_mutex.c | 5 +++-- sys/kern/kern_rwlock.c | 9 +++++---- sys/kern/kern_sx.c | 8 +++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index bc03a722401..f44b44e7efc 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -233,7 +233,8 @@ __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file, int line) m = mtxlock2mtx(c); - KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), + KASSERT(kdb_active != 0 || SCHEDULER_STOPPED() || + !TD_IS_IDLETHREAD(curthread), ("mtx_lock() by idle thread %p on sleep mutex %s @ %s:%d", curthread, m->lock_object.lo_name, file, line)); KASSERT(m->mtx_lock != MTX_DESTROYED, @@ -390,7 +391,7 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line) m = mtxlock2mtx(c); - KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), + KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(td), ("mtx_trylock() by idle thread %p on sleep mutex %s @ %s:%d", curthread, m->lock_object.lo_name, file, line)); KASSERT(m->mtx_lock != MTX_DESTROYED, diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index 988a44ade67..c8b1d7ca716 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -269,7 +269,8 @@ _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line) rw = rwlock2rw(c); - KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), + KASSERT(kdb_active != 0 || SCHEDULER_STOPPED() || + !TD_IS_IDLETHREAD(curthread), ("rw_wlock() by idle thread %p on rwlock %s @ %s:%d", curthread, rw->lock_object.lo_name, file, line)); KASSERT(rw->rw_lock != RW_DESTROYED, @@ -305,7 +306,7 @@ __rw_try_wlock(volatile uintptr_t *c, const char *file, int line) rw = rwlock2rw(c); - KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), + KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(td), ("rw_try_wlock() by idle thread %p on rwlock %s @ %s:%d", curthread, rw->lock_object.lo_name, file, line)); KASSERT(rw->rw_lock != RW_DESTROYED, @@ -615,7 +616,8 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line) td = curthread; rw = rwlock2rw(c); - KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(td), + KASSERT(kdb_active != 0 || SCHEDULER_STOPPED_TD(td) || + !TD_IS_IDLETHREAD(td), ("rw_rlock() by idle thread %p on rwlock %s @ %s:%d", td, rw->lock_object.lo_name, file, line)); KASSERT(rw->rw_lock != RW_DESTROYED, @@ -816,7 +818,6 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line) TD_LOCKS_DEC(curthread); } - /* * This function is called when we are unable to obtain a write lock on the * first try. This means that at least one other thread holds either a diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index 84414960b58..b05a702e13a 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -295,7 +295,8 @@ _sx_xlock(struct sx *sx, int opts, const char *file, int line) uintptr_t tid, x; int error = 0; - KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), + KASSERT(kdb_active != 0 || SCHEDULER_STOPPED() || + !TD_IS_IDLETHREAD(curthread), ("sx_xlock() by idle thread %p on sx %s @ %s:%d", curthread, sx->lock_object.lo_name, file, line)); KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, @@ -332,7 +333,7 @@ sx_try_xlock_(struct sx *sx, const char *file, int line) if (SCHEDULER_STOPPED_TD(td)) return (1); - KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), + KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(td), ("sx_try_xlock() by idle thread %p on sx %s @ %s:%d", curthread, sx->lock_object.lo_name, file, line)); KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, @@ -1030,7 +1031,8 @@ _sx_slock(struct sx *sx, int opts, const char *file, int line) uintptr_t x; int error; - KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), + KASSERT(kdb_active != 0 || SCHEDULER_STOPPED() || + !TD_IS_IDLETHREAD(curthread), ("sx_slock() by idle thread %p on sx %s @ %s:%d", curthread, sx->lock_object.lo_name, file, line)); KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,