Hi.
Try to catch more places where we sleep and are not allowed.
One thing of note, msleep() is missing in this diff, but there
it is needed to call to sleep_setup routines with the mutex
held, and after we release it we _will_ sleep so a sleep there
with another mutex held will be caught by the assertwaitok()
in mi_switch().
Also, define assertwaitok() out for !DIAGNOSTIC kernels.
Comments/OKs?
Index: kern/kern_rwlock.c
===================================================================
RCS file: /home/cvs/src/sys/kern/kern_rwlock.c,v
retrieving revision 1.16
diff -u -p -r1.16 kern_rwlock.c
--- kern/kern_rwlock.c 24 Sep 2010 13:21:30 -0000 1.16
+++ kern/kern_rwlock.c 30 Sep 2010 00:12:12 -0000
@@ -87,6 +87,8 @@ rw_enter_read(struct rwlock *rwl)
{
unsigned long owner = rwl->rwl_owner;
+ assertwaitok();
+
if (__predict_false((owner & RWLOCK_WRLOCK) ||
rw_cas(&rwl->rwl_owner, owner, owner + RWLOCK_READ_INCR)))
rw_enter(rwl, RW_READ);
@@ -97,6 +99,8 @@ rw_enter_write(struct rwlock *rwl)
{
struct proc *p = curproc;
+ assertwaitok();
+
if (__predict_false(rw_cas(&rwl->rwl_owner, 0,
RW_PROC(p) | RWLOCK_WRLOCK)))
rw_enter(rwl, RW_WRITE);
@@ -190,6 +194,9 @@ rw_enter(struct rwlock *rwl, int flags)
struct sleep_state sls;
unsigned long inc, o;
int error;
+
+ if (!(flags & RW_NOSLEEP))
+ assertwaitok();
op = &rw_ops[flags & RW_OPMASK];
Index: kern/kern_synch.c
===================================================================
RCS file: /home/cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.95
diff -u -p -r1.95 kern_synch.c
--- kern/kern_synch.c 29 Jun 2010 00:28:14 -0000 1.95
+++ kern/kern_synch.c 29 Sep 2010 21:55:58 -0000
@@ -121,6 +121,8 @@ tsleep(const volatile void *ident, int p
return (0);
}
+ assertwaitok();
+
sleep_setup(&sls, ident, priority, wmesg);
sleep_setup_timeout(&sls, timo);
sleep_setup_signal(&sls, priority);
Index: kern/subr_pool.c
===================================================================
RCS file: /home/cvs/src/sys/kern/subr_pool.c,v
retrieving revision 1.98
diff -u -p -r1.98 subr_pool.c
--- kern/subr_pool.c 26 Sep 2010 21:03:57 -0000 1.98
+++ kern/subr_pool.c 30 Sep 2010 00:03:15 -0000
@@ -455,10 +455,8 @@ pool_get(struct pool *pp, int flags)
KASSERT(flags & (PR_WAITOK | PR_NOWAIT));
-#ifdef DIAGNOSTIC
if ((flags & PR_WAITOK) != 0)
assertwaitok();
-#endif /* DIAGNOSTIC */
mtx_enter(&pp->pr_mtx);
v = pool_do_get(pp, flags);
Index: kern/subr_xxx.c
===================================================================
RCS file: /home/cvs/src/sys/kern/subr_xxx.c,v
retrieving revision 1.12
diff -u -p -r1.12 subr_xxx.c
--- kern/subr_xxx.c 28 Sep 2010 20:27:56 -0000 1.12
+++ kern/subr_xxx.c 29 Sep 2010 21:55:03 -0000
@@ -156,13 +156,15 @@ blktochr(dev_t dev)
/*
* Check that we're in a context where it's okay to sleep.
*/
+
+#ifdef DIAGNOSTIC
void
assertwaitok(void)
{
splassert(IPL_NONE);
-#ifdef DIAGNOSTIC
+
if (curcpu()->ci_mutex_level != 0)
panic("assertwaitok: non-zero mutex count: %d",
curcpu()->ci_mutex_level);
-#endif
}
+#endif
Index: sys/systm.h
===================================================================
RCS file: /home/cvs/src/sys/sys/systm.h,v
retrieving revision 1.86
diff -u -p -r1.86 systm.h
--- sys/systm.h 21 Sep 2010 01:09:10 -0000 1.86
+++ sys/systm.h 30 Sep 2010 00:02:51 -0000
@@ -179,7 +179,11 @@ void ttyprintf(struct tty *, const char
void splassert_fail(int, int, const char *);
extern int splassert_ctl;
+#ifdef DIAGNOSTIC
void assertwaitok(void);
+#else
+#define assertwaitok() do { /* nothing */ } while (0)
+#endif
void tablefull(const char *);