Index: sys/kern/kern_sig.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_sig.c,v retrieving revision 1.369 diff -u -r1.369 kern_sig.c --- sys/kern/kern_sig.c 12 Oct 2019 19:57:09 -0000 1.369 +++ sys/kern/kern_sig.c 12 Oct 2019 20:40:45 -0000 @@ -126,6 +126,7 @@ static int sigput(sigpend_t *, struct proc *, ksiginfo_t *); static int sigunwait(struct proc *, const ksiginfo_t *); static void sigswitch(int, int, bool); +static void sigswitch_unlock_and_switch_away(struct proc *, struct lwp *); static void sigacts_poolpage_free(struct pool *, void *); static void *sigacts_poolpage_alloc(struct pool *, int); @@ -932,10 +933,11 @@ * The process is already stopping. */ if ((p->p_sflag & PS_STOPPING) != 0) { - sigswitch(0, p->p_xsig, true); + mutex_exit(proc_lock); + sigswitch_unlock_and_switch_away(p, l); mutex_enter(proc_lock); mutex_enter(p->p_lock); - goto repeat; /* XXX */ + goto repeat; } mask = &l->l_sigmask; @@ -1642,10 +1644,11 @@ * The process is already stopping. */ if ((p->p_sflag & PS_STOPPING) != 0) { - sigswitch(0, p->p_xsig, true); + mutex_exit(proc_lock); + sigswitch_unlock_and_switch_away(p, l); mutex_enter(proc_lock); mutex_enter(p->p_lock); - goto repeat; /* XXX */ + goto repeat; } KSI_INIT_TRAP(&ksi); @@ -1692,7 +1695,6 @@ { struct lwp *l = curlwp; struct proc *p = l->l_proc; - int biglocks; KASSERT(mutex_owned(p->p_lock)); KASSERT(l->l_stat == LSONPROC); @@ -1752,10 +1754,23 @@ mutex_exit(proc_lock); } - /* - * Unlock and switch away. - */ + sigswitch_unlock_and_switch_away(p, l); +} + +/* + * Unlock and switch away. + */ +static void +sigswitch_unlock_and_switch_away(struct proc *p, struct lwp *l) +{ + int biglocks; + + KASSERT(mutex_owned(p->p_lock)); KASSERT(!mutex_owned(proc_lock)); + + KASSERT(l->l_stat == LSONPROC); + KASSERT(p->p_nrlwps > 0); + KERNEL_UNLOCK_ALL(l, &biglocks); if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) { p->p_nrlwps--; @@ -1845,7 +1860,7 @@ * we awaken, check for a signal from the debugger. */ if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) { - sigswitch(PS_NOCLDSTOP, 0, false); + sigswitch_unlock_and_switch_away(p, l); mutex_enter(p->p_lock); signo = sigchecktrace(); } else if (p->p_stat == SACTIVE) @@ -2527,9 +2542,9 @@ * The process is already stopping. */ if ((p->p_sflag & PS_STOPPING) != 0) { - sigswitch(0, p->p_xsig, false); + sigswitch_unlock_and_switch_away(p, l); mutex_enter(p->p_lock); - goto repeat; /* XXX */ + goto repeat; } /* Needed for ktrace */