On Thu, Sep 30, 2010 at 12:29:54AM +0000, Thordur Bjornsson wrote:
> 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.
Noone wants to OK/comment on this besides matthew@ ?
>
> 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 *);