kernel = Fix tsleep(), remove MAILBOX signals, change signalset locks for LWPs
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 12 Nov 2011 06:27:22 +0000 (22:27 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 12 Nov 2011 06:27:22 +0000 (22:27 -0800)
* 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.

18 files changed:
sys/cpu/i386/include/pmap.h
sys/cpu/x86_64/include/pmap.h
sys/emulation/linux/linux_misc.c
sys/kern/init_main.c
sys/kern/kern_fork.c
sys/kern/kern_sig.c
sys/kern/kern_synch.c
sys/platform/pc32/i386/machdep.c
sys/platform/pc64/x86_64/machdep.c
sys/platform/vkernel/i386/cpu_regs.c
sys/platform/vkernel64/x86_64/cpu_regs.c
sys/sys/proc.h
sys/sys/signal.h
sys/sys/signal2.h
sys/sys/signalvar.h
sys/vfs/mfs/mfs_vfsops.c
sys/vfs/procfs/procfs_ctl.c
sys/vm/vm_vmspace.c

index f7f0def..761752a 100644 (file)
  * 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_ */
index d8a5fec..82072e5 100644 (file)
  * 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_ */
index 336fb7d..c3b97c0 100644 (file)
@@ -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;
index 0b9d6e0..97b985d 100644 (file)
@@ -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;
index 9abddd0..e174167 100644 (file)
@@ -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
index 9fc1c3c..4687e95 100644 (file)
@@ -69,6 +69,7 @@
 
 #include <sys/signal2.h>
 #include <sys/thread2.h>
+#include <sys/spinlock2.h>
 
 #include <machine/cpu.h>
 #include <machine/smp.h>
@@ -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:
-       ;
 }
 
 /*
index 4f680fd..6d182a9 100644 (file)
@@ -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)) ==
index 12d89c7..5297aac 100644 (file)
@@ -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
index 1fee322..bf2dada 100644 (file)
@@ -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
index 206a210..eeb5f6b 100644 (file)
@@ -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
index 66ce00f..426dccf 100644 (file)
@@ -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
index 61029f8..3417601 100644 (file)
@@ -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 */
 
index ca5f06b..dd8ab58 100644 (file)
@@ -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 */
 
index cebeaf9..701c179 100644 (file)
@@ -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)
index 67889a4..5f2067e 100644 (file)
@@ -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;
 };
index 8ecfd3b..07ea2dc 100644 (file)
@@ -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))
index c8f9216..a6f0c0b 100644 (file)
@@ -53,6 +53,7 @@
 #include <sys/signal2.h>
 #include <sys/thread2.h>
 #include <sys/mplock2.h>
+#include <sys/spinlock2.h>
 
 #include <vm/vm.h>
 
@@ -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) {
index 7f4c1eb..7002b17 100644 (file)
@@ -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:
                /*