diff options
author | davidxu <davidxu@FreeBSD.org> | 2005-08-19 13:35:34 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2005-08-19 13:35:34 +0000 |
commit | bce3f5771d336507ba59a1c7f1c0fc825e92a874 (patch) | |
tree | 07ff9efc7df0cd2edc792f5410cc9e1fa89023dd | |
parent | 8d1d5878f983c30d8849cbee1143124f37131f2c (diff) | |
download | FreeBSD-src-bce3f5771d336507ba59a1c7f1c0fc825e92a874.zip FreeBSD-src-bce3f5771d336507ba59a1c7f1c0fc825e92a874.tar.gz |
Fix a LOR between sched_lock and sleep queue lock.
-rw-r--r-- | sys/kern/kern_kse.c | 9 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 6 |
2 files changed, 8 insertions, 7 deletions
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index 5f49313..827fb66 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -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); - } } } } diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 11b66da..f1157ca 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -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); |