The previous commit wasn't entirely correct. At least one goto to the
out: label in psignal() did not grab sched_lock before trying to release it. Also, the previous version had several cases where it grabbed sched_lock before jumping to out: unneccessarily, so rework this a bit. The runfast: and out: labels must be called with sched_lock released, and the run: label must be called with it held. Appropriate mtx_assert()'s have been added that should catch any bugs that may still be in this code. Noticed by: bde
This commit is contained in:
parent
542e394c1c
commit
3e6831f510
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=70603
@ -1123,8 +1123,10 @@ psignal(p, sig)
|
|||||||
* be noticed when the process returns through
|
* be noticed when the process returns through
|
||||||
* trap() or syscall().
|
* trap() or syscall().
|
||||||
*/
|
*/
|
||||||
if ((p->p_flag & P_SINTR) == 0)
|
if ((p->p_flag & P_SINTR) == 0) {
|
||||||
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Process is sleeping and traced... make it runnable
|
* Process is sleeping and traced... make it runnable
|
||||||
* so it can discover the signal in issignal() and stop
|
* so it can discover the signal in issignal() and stop
|
||||||
@ -1132,15 +1134,14 @@ psignal(p, sig)
|
|||||||
*/
|
*/
|
||||||
if (p->p_flag & P_TRACED)
|
if (p->p_flag & P_TRACED)
|
||||||
goto run;
|
goto run;
|
||||||
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
/*
|
/*
|
||||||
* If SIGCONT is default (or ignored) and process is
|
* If SIGCONT is default (or ignored) and process is
|
||||||
* asleep, we are finished; the process should not
|
* asleep, we are finished; the process should not
|
||||||
* be awakened.
|
* be awakened.
|
||||||
*/
|
*/
|
||||||
mtx_exit(&sched_lock, MTX_SPIN);
|
|
||||||
if ((prop & SA_CONT) && action == SIG_DFL) {
|
if ((prop & SA_CONT) && action == SIG_DFL) {
|
||||||
SIGDELSET(p->p_siglist, sig);
|
SIGDELSET(p->p_siglist, sig);
|
||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -1150,10 +1151,8 @@ psignal(p, sig)
|
|||||||
* cause the process to run.
|
* cause the process to run.
|
||||||
*/
|
*/
|
||||||
if (prop & SA_STOP) {
|
if (prop & SA_STOP) {
|
||||||
if (action != SIG_DFL) {
|
if (action != SIG_DFL)
|
||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
|
||||||
goto runfast;
|
goto runfast;
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* If a child holding parent blocked,
|
* If a child holding parent blocked,
|
||||||
* stopping could cause deadlock.
|
* stopping could cause deadlock.
|
||||||
@ -1167,12 +1166,9 @@ psignal(p, sig)
|
|||||||
psignal(p->p_pptr, SIGCHLD);
|
psignal(p->p_pptr, SIGCHLD);
|
||||||
stop(p);
|
stop(p);
|
||||||
PROCTREE_LOCK(PT_RELEASE);
|
PROCTREE_LOCK(PT_RELEASE);
|
||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
} else
|
||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
|
||||||
goto runfast;
|
goto runfast;
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
|
||||||
case SSTOP:
|
case SSTOP:
|
||||||
@ -1180,8 +1176,11 @@ psignal(p, sig)
|
|||||||
* If traced process is already stopped,
|
* If traced process is already stopped,
|
||||||
* then no further action is necessary.
|
* then no further action is necessary.
|
||||||
*/
|
*/
|
||||||
if (p->p_flag & P_TRACED)
|
if (p->p_flag & P_TRACED) {
|
||||||
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kill signal always sets processes running.
|
* Kill signal always sets processes running.
|
||||||
@ -1189,7 +1188,6 @@ psignal(p, sig)
|
|||||||
if (sig == SIGKILL)
|
if (sig == SIGKILL)
|
||||||
goto runfast;
|
goto runfast;
|
||||||
|
|
||||||
mtx_exit(&sched_lock, MTX_SPIN);
|
|
||||||
if (prop & SA_CONT) {
|
if (prop & SA_CONT) {
|
||||||
/*
|
/*
|
||||||
* If SIGCONT is default (or ignored), we continue the
|
* If SIGCONT is default (or ignored), we continue the
|
||||||
@ -1203,12 +1201,13 @@ psignal(p, sig)
|
|||||||
*/
|
*/
|
||||||
if (action == SIG_DFL)
|
if (action == SIG_DFL)
|
||||||
SIGDELSET(p->p_siglist, sig);
|
SIGDELSET(p->p_siglist, sig);
|
||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
|
||||||
if (action == SIG_CATCH)
|
if (action == SIG_CATCH)
|
||||||
goto runfast;
|
goto runfast;
|
||||||
|
mtx_enter(&sched_lock, MTX_SPIN);
|
||||||
if (p->p_wchan == 0)
|
if (p->p_wchan == 0)
|
||||||
goto run;
|
goto run;
|
||||||
p->p_stat = SSLEEP;
|
p->p_stat = SSLEEP;
|
||||||
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1218,7 +1217,6 @@ psignal(p, sig)
|
|||||||
* (If we did the shell could get confused.)
|
* (If we did the shell could get confused.)
|
||||||
*/
|
*/
|
||||||
SIGDELSET(p->p_siglist, sig);
|
SIGDELSET(p->p_siglist, sig);
|
||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1231,6 +1229,7 @@ psignal(p, sig)
|
|||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
mtx_enter(&sched_lock, MTX_SPIN);
|
||||||
if (p->p_wchan && p->p_flag & P_SINTR)
|
if (p->p_wchan && p->p_flag & P_SINTR)
|
||||||
unsleep(p);
|
unsleep(p);
|
||||||
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1242,15 +1241,15 @@ psignal(p, sig)
|
|||||||
if (p == curproc) {
|
if (p == curproc) {
|
||||||
mtx_exit(&sched_lock, MTX_SPIN);
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
signotify(p);
|
signotify(p);
|
||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
|
||||||
}
|
}
|
||||||
#ifdef SMP
|
#ifdef SMP
|
||||||
else if (p->p_stat == SRUN) {
|
else if (p->p_stat == SRUN) {
|
||||||
mtx_exit(&sched_lock, MTX_SPIN);
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
forward_signal(p);
|
forward_signal(p);
|
||||||
mtx_enter(&sched_lock, MTX_SPIN);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else
|
||||||
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
@ -1259,12 +1258,17 @@ psignal(p, sig)
|
|||||||
/*
|
/*
|
||||||
* Raise priority to at least PUSER.
|
* Raise priority to at least PUSER.
|
||||||
*/
|
*/
|
||||||
|
mtx_enter(&sched_lock, MTX_SPIN);
|
||||||
if (p->p_priority > PUSER)
|
if (p->p_priority > PUSER)
|
||||||
p->p_priority = PUSER;
|
p->p_priority = PUSER;
|
||||||
run:
|
run:
|
||||||
|
/* If we jump here, sched_lock has to be owned. */
|
||||||
|
mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED);
|
||||||
setrunnable(p);
|
setrunnable(p);
|
||||||
out:
|
|
||||||
mtx_exit(&sched_lock, MTX_SPIN);
|
mtx_exit(&sched_lock, MTX_SPIN);
|
||||||
|
out:
|
||||||
|
/* If we jump here, sched_lock should not be owned. */
|
||||||
|
mtx_assert(&sched_lock, MA_NOTOWNED);
|
||||||
splx(s);
|
splx(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user