From 94f98873ae3f49c05cb6155508726f987a584cae Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 11 Nov 2011 22:27:22 -0800 Subject: [PATCH] kernel = Fix tsleep(), remove MAILBOX signals, change signalset locks for LWPs * tsleep() was improperly calling lwkt_gettoken() and potentially blocking prior to sleeping, which it isn't supposed to do. This may have been the cause of several odd panics and corruption, though no smoking gun was found. * Change access to lp->lwp_siglist to use a spinlock instead of a token. Add a per-LWP spinlock in addition to the per-LWP token. * Remove MAILBOX signals (which require p->p_token). These are no longer used. --- sys/cpu/i386/include/pmap.h | 5 -- sys/cpu/x86_64/include/pmap.h | 5 -- sys/emulation/linux/linux_misc.c | 5 +- sys/kern/init_main.c | 1 + sys/kern/kern_fork.c | 1 + sys/kern/kern_sig.c | 65 +++++++++--------------- sys/kern/kern_synch.c | 39 +++----------- sys/platform/pc32/i386/machdep.c | 15 ------ sys/platform/pc64/x86_64/machdep.c | 15 ------ sys/platform/vkernel/i386/cpu_regs.c | 15 ------ sys/platform/vkernel64/x86_64/cpu_regs.c | 15 ------ sys/sys/proc.h | 3 +- sys/sys/signal.h | 3 -- sys/sys/signal2.h | 5 ++ sys/sys/signalvar.h | 1 - sys/vfs/mfs/mfs_vfsops.c | 5 +- sys/vfs/procfs/procfs_ctl.c | 3 ++ sys/vm/vm_vmspace.c | 11 ---- 18 files changed, 50 insertions(+), 162 deletions(-) diff --git a/sys/cpu/i386/include/pmap.h b/sys/cpu/i386/include/pmap.h index f7f0deff4e..761752a54f 100644 --- a/sys/cpu/i386/include/pmap.h +++ b/sys/cpu/i386/include/pmap.h @@ -93,12 +93,7 @@ * PGEX_FPFAULT - Force the FP unit to generate a T_DNA fault if an * emulated user process tried to use it. This bit is * only used by vmspace_ctl(). - * - * PGEX_MAILBOX - Set in xflags by signal code to indicate that a mailbox - * signal was pending. Remerged on signal return. This - * bit is only used in a signal vector frame. */ -#define PGEX_MAILBOX 0x40 #define PGEX_FPFAULT 0x80 #endif /* !_CPU_PMAP_H_ */ diff --git a/sys/cpu/x86_64/include/pmap.h b/sys/cpu/x86_64/include/pmap.h index d8a5fecf06..82072e510b 100644 --- a/sys/cpu/x86_64/include/pmap.h +++ b/sys/cpu/x86_64/include/pmap.h @@ -98,12 +98,7 @@ * PGEX_FPFAULT - Force the FP unit to generate a T_DNA fault if an * emulated user process tried to use it. This bit is * only used by vmspace_ctl(). - * - * PGEX_MAILBOX - Set in xflags by signal code to indicate that a mailbox - * signal was pending. Remerged on signal return. This - * bit is only used in a signal vector frame. */ -#define PGEX_MAILBOX 0x40 #define PGEX_FPFAULT 0x80 #endif /* !_CPU_PMAP_H_ */ diff --git a/sys/emulation/linux/linux_misc.c b/sys/emulation/linux/linux_misc.c index 336fb7dfe9..c3b97c0751 100644 --- a/sys/emulation/linux/linux_misc.c +++ b/sys/emulation/linux/linux_misc.c @@ -1053,8 +1053,11 @@ sys_linux_wait4(struct linux_wait4_args *args) error = kern_wait(args->pid, args->status ? &status : NULL, options, args->rusage ? &rusage : NULL, &args->sysmsg_result); - if (error == 0) + if (error == 0) { + spin_lock(&lp->lwp_spin); lwp_delsig(lp, SIGCHLD); + spin_unlock(&lp->lwp_spin); + } if (error == 0 && args->status) { status &= 0xffff; diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 0b9d6e0921..97b985d4fd 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -177,6 +177,7 @@ mi_proc0init(struct globaldata *gd, struct user *proc0paddr) proc0.p_usched = usched_init(); lwp0.lwp_cpumask = (cpumask_t)-1; lwkt_token_init(&lwp0.lwp_token, "lwp_token"); + spin_init(&lwp0.lwp_spin); varsymset_init(&proc0.p_varsymset, NULL); thread0.td_flags |= TDF_RUNNING; thread0.td_proc = &proc0; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 9abddd0740..e174167e3c 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -636,6 +636,7 @@ lwp_fork(struct lwp *origlp, struct proc *destproc, int flags) crit_exit(); lp->lwp_cpumask &= usched_mastermask; lwkt_token_init(&lp->lwp_token, "lwp_token"); + spin_init(&lp->lwp_spin); /* * Assign the thread to the current cpu to begin with so we diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 9fc1c3c5ff..4687e956ef 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -69,6 +69,7 @@ #include #include +#include #include #include @@ -255,8 +256,6 @@ kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact) oact->sa_flags |= SA_NODEFER; if (SIGISMEMBER(ps->ps_siginfo, sig)) oact->sa_flags |= SA_SIGINFO; - if (SIGISMEMBER(ps->ps_sigmailbox, sig)) - oact->sa_flags |= SA_MAILBOX; if (sig == SIGCHLD && p->p_sigacts->ps_flag & PS_NOCLDSTOP) oact->sa_flags |= SA_NOCLDSTOP; if (sig == SIGCHLD && p->p_sigacts->ps_flag & PS_NOCLDWAIT) @@ -272,13 +271,6 @@ kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact) lwkt_reltoken(&p->p_token); return (EINVAL); } -#if 0 - /* (not needed, SIG_DFL forces action to occur) */ - if (act->sa_flags & SA_MAILBOX) { - lwkt_reltoken(&p->p_token); - return (EINVAL); - } -#endif } /* @@ -312,10 +304,6 @@ kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact) SIGADDSET(ps->ps_signodefer, sig); else SIGDELSET(ps->ps_signodefer, sig); - if (act->sa_flags & SA_MAILBOX) - SIGADDSET(ps->ps_sigmailbox, sig); - else - SIGDELSET(ps->ps_sigmailbox, sig); if (sig == SIGCHLD) { if (act->sa_flags & SA_NOCLDSTOP) p->p_sigacts->ps_flag |= PS_NOCLDSTOP; @@ -341,21 +329,18 @@ kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact) * and for signals set to SIG_DFL where the default is to * ignore. However, don't put SIGCONT in p_sigignore, as we * have to restart the process. + * + * Also remove the signal from the process and lwp signal + * list. */ if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN || (sigprop(sig) & SA_IGNORE && ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL)) { - /* never to be seen again */ SIGDELSET(p->p_siglist, sig); - /* - * Remove the signal also from the thread lists. - */ FOREACH_LWP_IN_PROC(lp, p) { - LWPHOLD(lp); - lwkt_gettoken(&lp->lwp_token); + spin_lock(&lp->lwp_spin); SIGDELSET(lp->lwp_siglist, sig); - lwkt_reltoken(&lp->lwp_token); - LWPRELE(lp); + spin_unlock(&lp->lwp_spin); } if (sig != SIGCONT) { /* easier in ksignal */ @@ -435,6 +420,7 @@ execsigs(struct proc *p) if (sig != SIGCONT) SIGADDSET(p->p_sigignore, sig); SIGDELSET(p->p_siglist, sig); + /* don't need spinlock */ SIGDELSET(lp->lwp_siglist, sig); } ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; @@ -1193,10 +1179,13 @@ lwpsignal(struct proc *p, struct lwp *lp, int sig) * Nobody can handle this signal, add it to the lwp or * process pending list */ - if (lp) + if (lp) { + spin_lock(&lp->lwp_spin); SIGADDSET(lp->lwp_siglist, sig); - else + spin_unlock(&lp->lwp_spin); + } else { SIGADDSET(p->p_siglist, sig); + } /* * If the process is stopped and is being traced, then no @@ -1354,7 +1343,9 @@ active_process: /* * Mark signal pending at this specific thread. */ + spin_lock(&lp->lwp_spin); SIGADDSET(lp->lwp_siglist, sig); + spin_unlock(&lp->lwp_spin); lwp_signotify(lp); @@ -1729,7 +1720,9 @@ kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout) error = 0; bzero(info, sizeof(*info)); info->si_signo = sig; + spin_lock(&lp->lwp_spin); lwp_delsig(lp, sig); /* take the signal! */ + spin_unlock(&lp->lwp_spin); if (sig == SIGKILL) { sigexit(lp, sig); @@ -1888,7 +1881,9 @@ issignal(struct lwp *lp, int maytrace) * only if P_TRACED was on when they were posted. */ if (SIGISMEMBER(p->p_sigignore, sig) && (traced == 0)) { + spin_lock(&lp->lwp_spin); lwp_delsig(lp, sig); + spin_unlock(&lp->lwp_spin); continue; } if (maytrace && (p->p_flag & P_TRACED) && (p->p_flag & P_PPWAIT) == 0) { @@ -1914,7 +1909,9 @@ issignal(struct lwp *lp, int maytrace) * then it will leave it in p->p_xstat; * otherwise we just look for signals again. */ + spin_lock(&lp->lwp_spin); lwp_delsig(lp, sig); /* clear old signal */ + spin_unlock(&lp->lwp_spin); sig = p->p_xstat; if (sig == 0) continue; @@ -2018,7 +2015,9 @@ issignal(struct lwp *lp, int maytrace) lwkt_reltoken(&p->p_token); return (sig); } + spin_lock(&lp->lwp_spin); lwp_delsig(lp, sig); /* take the signal! */ + spin_unlock(&lp->lwp_spin); } /* NOTREACHED */ } @@ -2054,7 +2053,9 @@ postsig(int sig) vkernel_trap(lp, tf); } + spin_lock(&lp->lwp_spin); lwp_delsig(lp, sig); + spin_unlock(&lp->lwp_spin); action = ps->ps_sigact[_SIG_IDX(sig)]; #ifdef KTRACE if (KTRPOINT(lp->lwp_thread, KTR_PSIG)) @@ -2093,22 +2094,6 @@ postsig(int sig) ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL; } - /* - * Handle the mailbox case. Copyout to the appropriate - * location but do not generate a signal frame. The system - * call simply returns EINTR and the user is responsible for - * polling the mailbox. - */ - if (SIGISMEMBER(ps->ps_sigmailbox, sig)) { - int sig_copy = sig; - copyout(&sig_copy, (void *)action, sizeof(int)); - lwkt_gettoken(&curproc->p_token); - curproc->p_flag |= P_MAILBOX; - lwkt_reltoken(&curproc->p_token); - crit_exit(); - goto done; - } - /* * Set the signal mask and calculate the mask to restore * when the signal function returns. @@ -2140,8 +2125,6 @@ postsig(int sig) } (*p->p_sysent->sv_sendsig)(action, sig, &returnmask, code); } -done: - ; } /* diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 4f680fdd33..6d182a97f7 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -488,6 +488,9 @@ tsleep_wakeup_remote(struct thread *td) * * During autoconfiguration or after a panic, a sleep will simply * lower the priority briefly to allow interrupts, then return. + * + * WARNING! This code can't block (short of switching away), or bad things + * will happen. No getting tokens, no blocking locks, etc. */ int tsleep(const volatile void *ident, int flags, const char *wmesg, int timo) @@ -498,7 +501,6 @@ tsleep(const volatile void *ident, int flags, const char *wmesg, int timo) globaldata_t gd; int sig; int catch; - int id; int error; int oldpri; struct callout thandle; @@ -553,7 +555,6 @@ tsleep(const volatile void *ident, int flags, const char *wmesg, int timo) * tokens or we can loose the wakeup. */ if ((flags & PINTERLOCKED) == 0) { - id = LOOKUP(ident); _tsleep_interlock(gd, ident, flags); } @@ -573,20 +574,9 @@ tsleep(const volatile void *ident, int flags, const char *wmesg, int timo) * Early termination only occurs when tsleep() is * entered while in a normal LSRUN state. */ - lwkt_gettoken(&lp->lwp_token); if ((sig = CURSIG(lp)) != 0) goto resume; - /* - * Early termination if PCATCH was set and a - * mailbox signal was possibly delivered prior to - * the system call even being made, in order to - * allow the user to interlock without having to - * make additional system calls. - */ - if (p->p_flag & P_MAILBOX) - goto resume; - /* * Causes ksignal to wake us up if a signal is * received (interlocked with p->p_token). @@ -708,21 +698,11 @@ tsleep(const volatile void *ident, int flags, const char *wmesg, int timo) /* * Figure out the correct error return. If interrupted by a * signal we want to return EINTR or ERESTART. - * - * If P_MAILBOX is set no automatic system call restart occurs - * and we return EINTR. P_MAILBOX is meant to be used as an - * interlock, the user must poll it prior to any system call - * that it wishes to interlock a mailbox signal against since - * the flag is cleared on *any* system call that sleeps. - * - * lp->lwp_token is held in the lwp && catch case. */ resume: if (p) { if (catch && error == 0) { - if ((p->p_flag & P_MAILBOX) && sig == 0) { - error = EINTR; - } else if (sig != 0 || (sig = CURSIG(lp))) { + if (sig != 0 || (sig = CURSIG(lp))) { if (SIGISMEMBER(p->p_sigacts->ps_sigintr, sig)) error = EINTR; else @@ -730,14 +710,6 @@ resume: } } lp->lwp_flag &= ~(LWP_BREAKTSLEEP | LWP_SINTR); - if (catch) - lwkt_reltoken(&lp->lwp_token); - if (p->p_flag & P_MAILBOX) { - lwkt_gettoken(&p->p_token); - p->p_flag &= ~P_MAILBOX; - lwkt_reltoken(&p->p_token); - } - } logtsleep1(tsleep_end); crit_exit_quick(td); @@ -881,6 +853,7 @@ endtsleep(void *arg) thread_t td = arg; struct lwp *lp; + KKASSERT(td->td_gd == mycpu); crit_enter(); /* @@ -899,7 +872,7 @@ endtsleep(void *arg) /* * Only do nominal wakeup processing if TDF_TIMEOUT and * TDF_TSLEEP_DESCHEDULED are both still set. Otherwise - * we raced a wakeup or we began executed and raced due to + * we raced a wakeup or we began executing and raced due to * blocking in the token above, and should do nothing. */ if ((td->td_flags & (TDF_TIMEOUT | TDF_TSLEEP_DESCHEDULED)) == diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index 12d89c7ade..5297aac57f 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -423,10 +423,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) /* make the size of the saved context visible to userland */ sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); - /* save mailbox pending state for syscall interlock semantics */ - if (p->p_flag & P_MAILBOX) - sf.sf_uc.uc_mcontext.mc_xflags |= PGEX_MAILBOX; - /* Allocate and validate space for the signal handler context. */ if ((lp->lwp_flag & LWP_ALTSTACK) != 0 && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { @@ -602,7 +598,6 @@ int sys_sigreturn(struct sigreturn_args *uap) { struct lwp *lp = curthread->td_lwp; - struct proc *p = lp->lwp_proc; struct trapframe *regs; ucontext_t uc; ucontext_t *ucp; @@ -698,16 +693,6 @@ sys_sigreturn(struct sigreturn_args *uap) crit_enter(); npxpop(&ucp->uc_mcontext); - /* - * Merge saved signal mailbox pending flag to maintain interlock - * semantics against system calls. - */ - if (ucp->uc_mcontext.mc_xflags & PGEX_MAILBOX) { - lwkt_gettoken(&p->p_token); - p->p_flag |= P_MAILBOX; - lwkt_reltoken(&p->p_token); - } - if (ucp->uc_mcontext.mc_onstack & 1) lp->lwp_sigstk.ss_flags |= SS_ONSTACK; else diff --git a/sys/platform/pc64/x86_64/machdep.c b/sys/platform/pc64/x86_64/machdep.c index 1fee322309..bf2dada03b 100644 --- a/sys/platform/pc64/x86_64/machdep.c +++ b/sys/platform/pc64/x86_64/machdep.c @@ -447,10 +447,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) /* Make the size of the saved context visible to userland */ sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); - /* Save mailbox pending state for syscall interlock semantics */ - if (p->p_flag & P_MAILBOX) - sf.sf_uc.uc_mcontext.mc_xflags |= PGEX_MAILBOX; - /* Allocate and validate space for the signal handler context. */ if ((lp->lwp_flag & LWP_ALTSTACK) != 0 && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { @@ -619,7 +615,6 @@ int sys_sigreturn(struct sigreturn_args *uap) { struct lwp *lp = curthread->td_lwp; - struct proc *p = lp->lwp_proc; struct trapframe *regs; ucontext_t uc; ucontext_t *ucp; @@ -719,16 +714,6 @@ sys_sigreturn(struct sigreturn_args *uap) crit_enter(); npxpop(&ucp->uc_mcontext); - /* - * Merge saved signal mailbox pending flag to maintain interlock - * semantics against system calls. - */ - if (ucp->uc_mcontext.mc_xflags & PGEX_MAILBOX) { - lwkt_gettoken(&p->p_token); - p->p_flag |= P_MAILBOX; - lwkt_reltoken(&p->p_token); - } - if (ucp->uc_mcontext.mc_onstack & 1) lp->lwp_sigstk.ss_flags |= SS_ONSTACK; else diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 206a2105d3..eeb5f6bdac 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -235,11 +235,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) /* make the size of the saved context visible to userland */ sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); - /* save mailbox pending state for syscall interlock semantics */ - if (p->p_flag & P_MAILBOX) - sf.sf_uc.uc_mcontext.mc_xflags |= PGEX_MAILBOX; - - /* Allocate and validate space for the signal handler context. */ if ((lp->lwp_flag & LWP_ALTSTACK) != 0 && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { @@ -501,16 +496,6 @@ sys_sigreturn(struct sigreturn_args *uap) crit_enter(); npxpop(&ucp.uc_mcontext); - /* - * Merge saved signal mailbox pending flag to maintain interlock - * semantics against system calls. - */ - if (ucp.uc_mcontext.mc_xflags & PGEX_MAILBOX) { - lwkt_gettoken(&p->p_token); - p->p_flag |= P_MAILBOX; - lwkt_reltoken(&p->p_token); - } - if (ucp.uc_mcontext.mc_onstack & 1) lp->lwp_sigstk.ss_flags |= SS_ONSTACK; else diff --git a/sys/platform/vkernel64/x86_64/cpu_regs.c b/sys/platform/vkernel64/x86_64/cpu_regs.c index 66ce00fb40..426dccfbcf 100644 --- a/sys/platform/vkernel64/x86_64/cpu_regs.c +++ b/sys/platform/vkernel64/x86_64/cpu_regs.c @@ -236,10 +236,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) /* Make the size of the saved context visible to userland */ sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); - /* Save mailbox pending state for syscall interlock semantics */ - if (p->p_flag & P_MAILBOX) - sf.sf_uc.uc_mcontext.mc_xflags |= PGEX_MAILBOX; - /* Allocate and validate space for the signal handler context. */ if ((lp->lwp_flag & LWP_ALTSTACK) != 0 && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { @@ -406,7 +402,6 @@ int sys_sigreturn(struct sigreturn_args *uap) { struct lwp *lp = curthread->td_lwp; - struct proc *p = lp->lwp_proc; struct trapframe *regs; ucontext_t uc; ucontext_t *ucp; @@ -506,16 +501,6 @@ sys_sigreturn(struct sigreturn_args *uap) */ npxpop(&ucp->uc_mcontext); - /* - * Merge saved signal mailbox pending flag to maintain interlock - * semantics against system calls. - */ - if (ucp->uc_mcontext.mc_xflags & PGEX_MAILBOX) { - lwkt_gettoken(&p->p_token); - p->p_flag |= P_MAILBOX; - lwkt_reltoken(&p->p_token); - } - if (ucp->uc_mcontext.mc_onstack & 1) lp->lwp_sigstk.ss_flags |= SS_ONSTACK; else diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 61029f8a33..341760199d 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -221,6 +221,7 @@ struct lwp { struct kqueue lwp_kqueue; /* for select/poll */ u_int lwp_kqueue_serial; struct lwkt_token lwp_token; /* per-lwp token for signal/state */ + struct spinlock lwp_spin; /* spinlock for signal handling */ }; struct proc { @@ -353,7 +354,7 @@ struct proc { /* Should probably be changed into a hold count. */ /* was P_NOSWAP 0x08000 was: Do not swap upages; p->p_hold */ -#define P_MAILBOX 0x10000 /* Possible mailbox signal pending */ +#define P_UNUSED7 0x10000 #define P_UPCALLPEND 0x20000 /* an upcall is pending */ diff --git a/sys/sys/signal.h b/sys/sys/signal.h index ca5f06b7cc..dd8ab581f7 100644 --- a/sys/sys/signal.h +++ b/sys/sys/signal.h @@ -270,7 +270,6 @@ struct sigaction { union { void (*__sa_handler) (int); void (*__sa_sigaction) (int, struct __siginfo *, void *); - int *__sa_mailbox; } __sigaction_u; /* signal handler */ int sa_flags; /* see signal options below */ sigset_t sa_mask; /* signal mask to apply */ @@ -284,7 +283,6 @@ struct sigaction { #if !defined(_POSIX_SOURCE) #define sa_sigaction __sigaction_u.__sa_sigaction -#define sa_mailbox __sigaction_u.__sa_mailbox #define SA_ONSTACK 0x0001 /* take signal on signal stack */ #define SA_RESTART 0x0002 /* restart system call on signal return */ @@ -295,7 +293,6 @@ struct sigaction { #ifdef COMPAT_SUNOS #define SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */ #endif -#define SA_MAILBOX 0x1000 /* store to mailbox */ #define NSIG 64 /* size of sigptbl */ diff --git a/sys/sys/signal2.h b/sys/sys/signal2.h index cebeaf9c51..701c1798d4 100644 --- a/sys/sys/signal2.h +++ b/sys/sys/signal2.h @@ -45,6 +45,9 @@ */ /* * Determine which signals are pending for a lwp. + * + * (Does not need to be interlocked with lwp_spin. If caller holds a + * critical section races will be resolved through an AST). */ static __inline sigset_t lwp_sigpend(struct lwp *lp) @@ -58,6 +61,8 @@ lwp_sigpend(struct lwp *lp) /* * Mark a signal as handled by the lwp. + * + * (p->p_token must be held, lp->lwp_spin must be held) */ static __inline void lwp_delsig(struct lwp *lp, int sig) diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 67889a4bca..5f2067e9be 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -69,7 +69,6 @@ struct sigacts { sigset_t ps_signodefer; /* signals not masked while handled */ sigset_t ps_siginfo; /* signals that want SA_SIGINFO args */ sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX */ - sigset_t ps_sigmailbox; /* signals that update a mailbox */ unsigned int ps_refcnt; int ps_flag; }; diff --git a/sys/vfs/mfs/mfs_vfsops.c b/sys/vfs/mfs/mfs_vfsops.c index 8ecfd3b51c..07ea2dc45d 100644 --- a/sys/vfs/mfs/mfs_vfsops.c +++ b/sys/vfs/mfs/mfs_vfsops.c @@ -477,8 +477,11 @@ mfs_start(struct mount *mp, int flags) if (dounmount(mp, 0) != 0) { KKASSERT(td->td_proc); sig = CURSIG(td->td_lwp); - if (sig) + if (sig) { + spin_lock(&td->td_lwp->lwp_spin); lwp_delsig(td->td_lwp, sig); + spin_unlock(&td->td_lwp->lwp_spin); + } } } else if (tsleep((caddr_t)mfsp, PCATCH, "mfsidl", 0)) diff --git a/sys/vfs/procfs/procfs_ctl.c b/sys/vfs/procfs/procfs_ctl.c index c8f9216c3e..a6f0c0b9ee 100644 --- a/sys/vfs/procfs/procfs_ctl.c +++ b/sys/vfs/procfs/procfs_ctl.c @@ -53,6 +53,7 @@ #include #include #include +#include #include @@ -211,7 +212,9 @@ procfs_control(struct proc *curp, struct lwp *lp, int op) p->p_flag &= ~P_TRACED; /* remove pending SIGTRAP, else the process will die */ + spin_lock(&lp->lwp_spin); lwp_delsig(lp, SIGTRAP); + spin_unlock(&lp->lwp_spin); /* give process back to original parent */ if (p->p_oppid != p->p_pptr->p_pid) { diff --git a/sys/vm/vm_vmspace.c b/sys/vm/vm_vmspace.c index 7f4c1ebc7f..7002b177db 100644 --- a/sys/vm/vm_vmspace.c +++ b/sys/vm/vm_vmspace.c @@ -199,17 +199,6 @@ sys_vmspace_ctl(struct vmspace_ctl_args *uap) goto done; } - /* - * Signal mailbox interlock - */ - if (p->p_flag & P_MAILBOX) { - lwkt_gettoken(&p->p_token); - p->p_flag &= ~P_MAILBOX; - lwkt_reltoken(&p->p_token); - error = EINTR; - goto done; - } - switch(uap->cmd) { case VMSPACE_CTL_RUN: /* -- 2.41.0