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 *);

Reply via email to