diff options
| author | akolb <none@none> | 2007-09-04 15:02:11 -0700 |
|---|---|---|
| committer | akolb <none@none> | 2007-09-04 15:02:11 -0700 |
| commit | b7e32555fc1a5af52617bd619aa97d5e6868f7ef (patch) | |
| tree | d886959e6f76e4e6fd193eb4eff663148662a4cf /usr/src/uts/common/os/waitq.c | |
| parent | fe13b8ce8dfbfa2bdfc6fe9d3cc6fd5d9714f1b1 (diff) | |
| download | illumos-joyent-b7e32555fc1a5af52617bd619aa97d5e6868f7ef.tar.gz | |
6598427 waitq_runall() doesn't like being interrupted
Diffstat (limited to 'usr/src/uts/common/os/waitq.c')
| -rw-r--r-- | usr/src/uts/common/os/waitq.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/usr/src/uts/common/os/waitq.c b/usr/src/uts/common/os/waitq.c index 802d7afdc4..276026a02e 100644 --- a/usr/src/uts/common/os/waitq.c +++ b/usr/src/uts/common/os/waitq.c @@ -266,10 +266,11 @@ waitq_dequeue(waitq_t *wq, kthread_t *t) DTRACE_SCHED1(cpucaps__wakeup, kthread_t *, t); /* - * Change thread to transition state without dropping - * the wait queue lock. + * Change thread to transition state and drop the wait queue lock. The + * thread will remain locked since its t_lockp points to the + * transition_lock. */ - THREAD_TRANSITION_NOLOCK(t); + THREAD_TRANSITION(t); } /* @@ -297,8 +298,6 @@ waitq_setrun(kthread_t *t) if (wq == NULL) panic("waitq_setrun: thread %p is not on waitq", t); waitq_dequeue(wq, t); - - disp_lock_exit_high(&wq->wq_lock); CL_SETRUN(t); } @@ -311,9 +310,13 @@ waitq_takeone(waitq_t *wq) kthread_t *t; disp_lock_enter(&wq->wq_lock); + /* + * waitq_dequeue drops wait queue lock but leaves the CPU at high PIL. + */ if ((t = wq->wq_first) != NULL) waitq_dequeue(wq, wq->wq_first); - disp_lock_exit(&wq->wq_lock); + else + disp_lock_exit(&wq->wq_lock); return (t); } @@ -328,8 +331,14 @@ waitq_runfirst(waitq_t *wq) t = waitq_takeone(wq); if (t != NULL) { + /* + * t should have transition lock held. + * CL_SETRUN() will replace it with dispq lock and keep it held. + * thread_unlock() will drop dispq lock and restore PIL. + */ + ASSERT(THREAD_LOCK_HELD(t)); CL_SETRUN(t); - thread_unlock(t); /* drops dispq lock */ + thread_unlock(t); } return (t); } |
