Fix a sleep queue race for KSE thread.
Reviewed by: jhb
This commit is contained in:
parent
3e0ded9327
commit
c008d51784
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user