summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2007-02-06 18:42:38 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2007-02-06 18:42:38 +0000
commit7bcb40987b41efda8dd493434be65ee5d6371643 (patch)
tree226d9329979a1f6cd588e7384676bd9cf8e3560e
parent09e30a1a861156e28f380f5a15736860313eb75d (diff)
Use atomic.h operation for manipulating p_siglist in struct proc. Solves
the problem with lost signals in MP kernels. miod@, kettenis@ ok
-rw-r--r--sys/compat/linux/linux_misc.c4
-rw-r--r--sys/kern/kern_sig.c30
-rw-r--r--sys/kern/sched_bsd.c4
-rw-r--r--sys/sys/proc.h3
-rw-r--r--sys/sys/signalvar.h4
5 files changed, 24 insertions, 21 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index cef5a180206..a88eab1f886 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_misc.c,v 1.59 2006/10/08 19:49:57 sturm Exp $ */
+/* $OpenBSD: linux_misc.c,v 1.60 2007/02/06 18:42:37 art Exp $ */
/* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */
/*-
@@ -185,7 +185,7 @@ linux_sys_wait4(p, v, retval)
if ((error = sys_wait4(p, &w4a, retval)))
return error;
- p->p_siglist &= ~sigmask(SIGCHLD);
+ atomic_clearbits_int(&p->p_siglist, sigmask(SIGCHLD));
if (status != NULL) {
if ((error = copyin(status, &tstat, sizeof tstat)))
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 5183532147a..acc868830d8 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.86 2007/01/17 23:08:18 art Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.87 2007/02/06 18:42:37 art Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -339,7 +339,7 @@ setsigvec(struct proc *p, int signum, struct sigaction *sa)
*/
if (sa->sa_handler == SIG_IGN ||
(sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
- p->p_siglist &= ~bit; /* never to be seen again */
+ atomic_clearbits_int(&p->p_siglist, bit);
if (signum != SIGCONT)
p->p_sigignore |= bit; /* easier in psignal */
p->p_sigcatch &= ~bit;
@@ -391,7 +391,7 @@ execsigs(struct proc *p)
if (sigprop[nc] & SA_IGNORE) {
if (nc != SIGCONT)
p->p_sigignore |= mask;
- p->p_siglist &= ~mask;
+ atomic_clearbits_int(&p->p_siglist, mask);
}
ps->ps_sigact[nc] = SIG_DFL;
}
@@ -842,7 +842,7 @@ psignal(struct proc *p, int signum)
LIST_FOREACH(q, &p->p_thrchildren, p_thrsib)
psignal(q, signum);
#endif
- p->p_siglist &= ~stopsigmask;
+ atomic_clearbits_int(&p->p_siglist, stopsigmask);
}
if (prop & SA_STOP) {
@@ -850,11 +850,11 @@ psignal(struct proc *p, int signum)
LIST_FOREACH(q, &p->p_thrchildren, p_thrsib)
psignal(q, signum);
#endif
- p->p_siglist &= ~contsigmask;
+ atomic_clearbits_int(&p->p_siglist, contsigmask);
p->p_flag &= ~P_CONTINUED;
}
- p->p_siglist |= mask;
+ atomic_setbits_int(&p->p_siglist, mask);
/*
* Defer further processing for signals which are held,
@@ -889,7 +889,7 @@ psignal(struct proc *p, int signum)
* be awakened.
*/
if ((prop & SA_CONT) && action == SIG_DFL) {
- p->p_siglist &= ~mask;
+ atomic_clearbits_int(&p->p_siglist, mask);
goto out;
}
/*
@@ -903,7 +903,7 @@ psignal(struct proc *p, int signum)
*/
if (p->p_flag & P_PPWAIT)
goto out;
- p->p_siglist &= ~mask;
+ atomic_clearbits_int(&p->p_siglist, mask);
p->p_xstat = signum;
if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
psignal(p->p_pptr, SIGCHLD);
@@ -945,7 +945,7 @@ psignal(struct proc *p, int signum)
p->p_flag |= P_CONTINUED;
wakeup(p->p_pptr);
if (action == SIG_DFL)
- p->p_siglist &= ~mask;
+ atomic_clearbits_int(&p->p_siglist, mask);
if (action == SIG_CATCH)
goto runfast;
if (p->p_wchan == 0)
@@ -959,7 +959,7 @@ psignal(struct proc *p, int signum)
* Already stopped, don't need to stop again.
* (If we did the shell could get confused.)
*/
- p->p_siglist &= ~mask; /* take it away */
+ atomic_clearbits_int(&p->p_siglist, mask);
goto out;
}
@@ -1024,7 +1024,7 @@ issignal(struct proc *p)
return (0);
signum = ffs((long)mask);
mask = sigmask(signum);
- p->p_siglist &= ~mask; /* take the signal! */
+ atomic_clearbits_int(&p->p_siglist, mask);
/*
* We should see pending but ignored signals
@@ -1061,7 +1061,9 @@ issignal(struct proc *p)
mask = sigmask(signum);
if ((p->p_sigmask & mask) != 0)
continue;
- p->p_siglist &= ~mask; /* take the signal! */
+
+ /* take the signal! */
+ atomic_clearbits_int(&p->p_siglist, mask);
}
prop = sigprop[signum];
@@ -1140,7 +1142,7 @@ issignal(struct proc *p)
/* NOTREACHED */
keep:
- p->p_siglist |= mask; /* leave the signal for later */
+ atomic_setbits_int(&p->p_siglist, mask); /*leave the signal for later */
return (signum);
}
@@ -1184,7 +1186,7 @@ postsig(int signum)
KERNEL_PROC_LOCK(p);
mask = sigmask(signum);
- p->p_siglist &= ~mask;
+ atomic_clearbits_int(&p->p_siglist, mask);
action = ps->ps_sigact[signum];
sigval.sival_ptr = 0;
type = SI_USER;
diff --git a/sys/kern/sched_bsd.c b/sys/kern/sched_bsd.c
index a62c5248b86..699f4dd807a 100644
--- a/sys/kern/sched_bsd.c
+++ b/sys/kern/sched_bsd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sched_bsd.c,v 1.9 2006/11/29 12:24:18 miod Exp $ */
+/* $OpenBSD: sched_bsd.c,v 1.10 2007/02/06 18:42:37 art Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*-
@@ -609,7 +609,7 @@ setrunnable(struct proc *p)
* while we were stopped), check for a signal from the debugger.
*/
if ((p->p_flag & P_TRACED) != 0 && p->p_xstat != 0)
- p->p_siglist |= sigmask(p->p_xstat);
+ atomic_setbits_int(&p->p_siglist, sigmask(p->p_xstat));
case SSLEEP:
unsleep(p); /* e.g. when sending signals */
break;
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 65ad8c42bf4..a86ea27d412 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.89 2006/11/29 12:24:18 miod Exp $ */
+/* $OpenBSD: proc.h,v 1.90 2007/02/06 18:42:37 art Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -45,6 +45,7 @@
#include <sys/queue.h>
#include <sys/timeout.h> /* For struct timeout. */
#include <sys/event.h> /* For struct klist */
+#include <machine/atomic.h>
#ifdef __HAVE_CPUINFO
#define curproc curcpu()->ci_curproc
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index 8618c280032..8853ab2c6f2 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: signalvar.h,v 1.15 2005/06/17 22:33:34 niklas Exp $ */
+/* $OpenBSD: signalvar.h,v 1.16 2007/02/06 18:42:37 art Exp $ */
/* $NetBSD: signalvar.h,v 1.17 1996/04/22 01:23:31 christos Exp $ */
/*
@@ -89,7 +89,7 @@ struct sigacts {
/*
* Clear a pending signal from a process.
*/
-#define CLRSIG(p, sig) { (p)->p_siglist &= ~sigmask(sig); }
+#define CLRSIG(p, sig) atomic_clearbits_int(&(p)->p_siglist, sigmask(sig))
/*
* Signal properties and actions.