Fix a sleep queue race for KSE thread.

Reviewed by: jhb
This commit is contained in:
David Xu 2006-02-23 00:13:58 +00:00
parent 3e0ded9327
commit c008d51784
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=155932
3 changed files with 26 additions and 54 deletions

View File

@ -192,18 +192,6 @@ cv_wait_sig(struct cv *cvp, struct mtx *mp)
sleepq_lock(cvp);
/*
* Don't bother sleeping if we are exiting and not the exiting
* thread or if our thread is marked as interrupted.
*/
mtx_lock_spin(&sched_lock);
rval = thread_sleep_check(td);
mtx_unlock_spin(&sched_lock);
if (rval != 0) {
sleepq_release(cvp);
return (rval);
}
cvp->cv_waiters++;
DROP_GIANT();
mtx_unlock(mp);
@ -315,18 +303,6 @@ cv_timedwait_sig(struct cv *cvp, struct mtx *mp, int timo)
sleepq_lock(cvp);
/*
* Don't bother sleeping if we are exiting and not the exiting
* thread or if our thread is marked as interrupted.
*/
mtx_lock_spin(&sched_lock);
rval = thread_sleep_check(td);
mtx_unlock_spin(&sched_lock);
if (rval != 0) {
sleepq_release(cvp);
return (rval);
}
cvp->cv_waiters++;
DROP_GIANT();
mtx_unlock(mp);

View File

@ -164,22 +164,11 @@ msleep(ident, mtx, priority, wmesg, timo)
if (TD_ON_SLEEPQ(td))
sleepq_remove(td, td->td_wchan);
flags = SLEEPQ_MSLEEP;
if (catch)
flags |= SLEEPQ_INTERRUPTIBLE;
sleepq_lock(ident);
if (catch) {
/*
* Don't bother sleeping if we are exiting and not the exiting
* thread or if our thread is marked as interrupted.
*/
mtx_lock_spin(&sched_lock);
rval = thread_sleep_check(td);
mtx_unlock_spin(&sched_lock);
if (rval != 0) {
sleepq_release(ident);
if (mtx != NULL && priority & PDROP)
mtx_unlock(mtx);
return (rval);
}
}
CTR5(KTR_PROC, "msleep: thread %p (pid %ld, %s) on %s (%p)",
(void *)td, (long)p->p_pid, p->p_comm, wmesg, ident);
@ -199,9 +188,6 @@ msleep(ident, mtx, priority, wmesg, timo)
* stopped, then td will no longer be on a sleep queue upon
* return from cursig().
*/
flags = SLEEPQ_MSLEEP;
if (catch)
flags |= SLEEPQ_INTERRUPTIBLE;
sleepq_add(ident, mtx, wmesg, flags);
if (timo)
sleepq_set_timeout(ident, timo);

View File

@ -387,23 +387,33 @@ sleepq_catch_signals(void *wchan)
mtx_unlock(&ps->ps_mtx);
}
if (ret) {
if (ret == 0) {
mtx_lock_spin(&sc->sc_lock);
/*
* Lock sched_lock before unlocking proc lock,
* without this, we could lose a race.
*/
mtx_lock_spin(&sched_lock);
PROC_UNLOCK(p);
if (!(td->td_flags & TDF_INTERRUPT))
return (0);
/* KSE threads tried unblocking us. */
ret = td->td_intrval;
mtx_unlock_spin(&sched_lock);
MPASS(ret == EINTR || ret == ERESTART);
} else {
PROC_UNLOCK(p);
/*
* If there were pending signals and this thread is still on
* the sleep queue, remove it from the sleep queue.
* If there were pending signals and this thread is still
* on the sleep queue, remove it from the sleep queue.
*/
mtx_lock_spin(&sc->sc_lock);
sq = sleepq_lookup(wchan);
mtx_lock_spin(&sched_lock);
if (TD_ON_SLEEPQ(td))
sleepq_resume_thread(sq, td, -1);
td->td_flags &= ~TDF_SINTR;
} else {
mtx_lock_spin(&sc->sc_lock);
mtx_lock_spin(&sched_lock);
PROC_UNLOCK(p);
}
sq = sleepq_lookup(wchan);
mtx_lock_spin(&sched_lock);
if (TD_ON_SLEEPQ(td))
sleepq_resume_thread(sq, td, -1);
td->td_flags &= ~TDF_SINTR;
return (ret);
}