Fix a LOR between sched_lock and sleep queue lock.

This commit is contained in:
David Xu 2005-08-19 13:35:34 +00:00
parent 8ddda52485
commit 8c6d7a8db8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149284
2 changed files with 8 additions and 7 deletions

View File

@ -707,8 +707,8 @@ kse_create(struct thread *td, struct kse_create_args *uap)
* Make the new upcall available to the ksegrp.
* It may or may not use it, but it's available.
*/
PROC_UNLOCK(p);
upcall_link(newku, newkg);
PROC_UNLOCK(p);
if (mbx.km_quantum)
newkg->kg_upquantum = max(1, mbx.km_quantum / tick);
@ -1441,7 +1441,7 @@ thread_continued(struct proc *p)
struct thread *td;
PROC_LOCK_ASSERT(p, MA_OWNED);
mtx_assert(&sched_lock, MA_OWNED);
KASSERT(P_SHOULDSTOP(p), "process not stopped");
if (!(p->p_flag & P_SA))
return;
@ -1455,11 +1455,10 @@ thread_continued(struct proc *p)
if (!(td->td_pflags & TDP_SA))
continue;
FOREACH_UPCALL_IN_GROUP(kg, ku) {
mtx_lock_spin(&sched_lock);
ku->ku_flags |= KUF_DOUPCALL;
mtx_unlock_spin(&sched_lock);
wakeup(&kg->kg_completed);
if (TD_IS_SUSPENDED(ku->ku_owner)) {
thread_unsuspend_one(ku->ku_owner);
}
}
}
}

View File

@ -788,7 +788,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
/* deliver or queue signal */
if (P_SHOULDSTOP(p)) {
p->p_xstat = data;
p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG);
mtx_lock_spin(&sched_lock);
if (saved_pid <= PID_MAX) {
p->p_xthread->td_flags &= ~TDF_XSIG;
@ -808,8 +807,11 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
* you should use PT_SUSPEND to suspend it before
* continuing process.
*/
thread_unsuspend(p);
mtx_unlock_spin(&sched_lock);
thread_continued(p);
p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG);
mtx_lock_spin(&sched_lock);
thread_unsuspend(p);
mtx_unlock_spin(&sched_lock);
} else if (data) {
psignal(p, data);