aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorJohn Birrell <jb@FreeBSD.org>2006-10-26 21:42:22 +0000
committerJohn Birrell <jb@FreeBSD.org>2006-10-26 21:42:22 +0000
commit8460a577a4b4ec185bd813188a5b188893b8c140 (patch)
tree2136d90e7e60f4ef25fe147499787d0e6a155b82 /sys/kern/kern_sig.c
parent50159fa2161d549dbe2cb3ff9db1cc3816d48c37 (diff)
downloadsrc-8460a577a4b4ec185bd813188a5b188893b8c140.tar.gz
src-8460a577a4b4ec185bd813188a5b188893b8c140.zip
Make KSE a kernel option, turned on by default in all GENERIC
kernel configs except sun4v (which doesn't process signals properly with KSE). Reviewed by: davidxu@
Notes
Notes: svn path=/head/; revision=163709
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index a975914cec32..a79039ce2432 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -94,7 +94,9 @@ static int filt_sigattach(struct knote *kn);
static void filt_sigdetach(struct knote *kn);
static int filt_signal(struct knote *kn, long hint);
static struct thread *sigtd(struct proc *p, int sig, int prop);
+#ifdef KSE
static int do_tdsignal(struct proc *, struct thread *, int, ksiginfo_t *);
+#endif
static void sigqueue_start(void);
static uma_zone_t ksiginfo_zone = NULL;
@@ -565,7 +567,11 @@ void
signotify(struct thread *td)
{
struct proc *p;
+#ifdef KSE
sigset_t set, saved;
+#else
+ sigset_t set;
+#endif
p = td->td_proc;
@@ -576,8 +582,10 @@ signotify(struct thread *td)
* previously masked by all threads to our sigqueue.
*/
set = p->p_sigqueue.sq_signals;
+#ifdef KSE
if (p->p_flag & P_SA)
saved = p->p_sigqueue.sq_signals;
+#endif
SIGSETNAND(set, td->td_sigmask);
if (! SIGISEMPTY(set))
sigqueue_move_set(&p->p_sigqueue, &td->td_sigqueue, &set);
@@ -586,6 +594,7 @@ signotify(struct thread *td)
td->td_flags |= TDF_NEEDSIGCHK | TDF_ASTPENDING;
mtx_unlock_spin(&sched_lock);
}
+#ifdef KSE
if ((p->p_flag & P_SA) && !(p->p_flag & P_SIGEVENT)) {
if (!SIGSETEQ(saved, p->p_sigqueue.sq_signals)) {
/* pending set changed */
@@ -593,6 +602,7 @@ signotify(struct thread *td)
wakeup(&p->p_siglist);
}
}
+#endif
}
int
@@ -744,11 +754,13 @@ kern_sigaction(td, sig, act, oact, flags)
if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN ||
(sigprop(sig) & SA_IGNORE &&
ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL)) {
+#ifdef KSE
if ((p->p_flag & P_SA) &&
SIGISMEMBER(p->p_sigqueue.sq_signals, sig)) {
p->p_flag |= P_SIGEVENT;
wakeup(&p->p_siglist);
}
+#endif
/* never to be seen again */
sigqueue_delete_proc(p, sig);
if (sig != SIGCONT)
@@ -1206,10 +1218,12 @@ restart:
continue;
if (!SIGISMEMBER(td->td_sigqueue.sq_signals, i)) {
if (SIGISMEMBER(p->p_sigqueue.sq_signals, i)) {
+#ifdef KSE
if (p->p_flag & P_SA) {
p->p_flag |= P_SIGEVENT;
wakeup(&p->p_siglist);
}
+#endif
sigqueue_move(&p->p_sigqueue,
&td->td_sigqueue, i);
} else
@@ -1882,7 +1896,9 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
{
struct sigacts *ps;
struct proc *p;
+#ifdef KSE
int error;
+#endif
int sig;
int code;
@@ -1891,6 +1907,7 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
code = ksi->ksi_code;
KASSERT(_SIG_VALID(sig), ("invalid signal"));
+#ifdef KSE
if (td->td_pflags & TDP_SA) {
if (td->td_mailbox == NULL)
thread_user_enter(td);
@@ -1908,6 +1925,9 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
} else {
PROC_LOCK(p);
}
+#else
+ PROC_LOCK(p);
+#endif
ps = p->p_sigacts;
mtx_lock(&ps->ps_mtx);
if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(ps->ps_sigcatch, sig) &&
@@ -1918,9 +1938,15 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)],
&td->td_sigmask, code);
#endif
+#ifdef KSE
if (!(td->td_pflags & TDP_SA))
(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)],
ksi, &td->td_sigmask);
+#else
+ (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)],
+ ksi, &td->td_sigmask);
+#endif
+#ifdef KSE
else if (td->td_mailbox == NULL) {
mtx_unlock(&ps->ps_mtx);
/* UTS caused a sync signal */
@@ -1939,6 +1965,7 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
sigexit(td, SIGSEGV);
mtx_lock(&ps->ps_mtx);
}
+#endif
SIGSETOR(td->td_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
if (!SIGISMEMBER(ps->ps_signodefer, sig))
SIGADDSET(td->td_sigmask, sig);
@@ -2052,6 +2079,7 @@ psignal_event(struct proc *p, struct sigevent *sigev, ksiginfo_t *ksi)
int
tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
{
+#ifdef KSE
sigset_t saved;
int ret;
@@ -2071,6 +2099,7 @@ tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
static int
do_tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
{
+#endif
sig_t action;
sigqueue_t *sigqueue;
int prop;
@@ -2081,9 +2110,17 @@ do_tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
PROC_LOCK_ASSERT(p, MA_OWNED);
if (!_SIG_VALID(sig))
+#ifdef KSE
panic("do_tdsignal(): invalid signal");
+#else
+ panic("tdsignal(): invalid signal");
+#endif
+#ifdef KSE
KASSERT(ksi == NULL || !KSI_ONQ(ksi), ("do_tdsignal: ksi on queue"));
+#else
+ KASSERT(ksi == NULL || !KSI_ONQ(ksi), ("tdsignal: ksi on queue"));
+#endif
/*
* IEEE Std 1003.1-2001: return success when killing a zombie.
@@ -2240,6 +2277,7 @@ do_tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
if (action == SIG_DFL) {
sigqueue_delete(sigqueue, sig);
} else if (action == SIG_CATCH) {
+#ifdef KSE
/*
* The process wants to catch it so it needs
* to run at least one thread, but which one?
@@ -2250,6 +2288,12 @@ do_tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
* single thread is runnable asap.
* XXXKSE for now however, make them all run.
*/
+#else
+ /*
+ * The process wants to catch it so it needs
+ * to run at least one thread, but which one?
+ */
+#endif
goto runfast;
}
/*
@@ -2541,8 +2585,10 @@ issignal(td)
*/
if (SIGISMEMBER(ps->ps_sigignore, sig) && (traced == 0)) {
sigqueue_delete(&td->td_sigqueue, sig);
+#ifdef KSE
if (td->td_pflags & TDP_SA)
SIGADDSET(td->td_sigmask, sig);
+#endif
continue;
}
if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
@@ -2553,9 +2599,11 @@ issignal(td)
newsig = ptracestop(td, sig);
mtx_lock(&ps->ps_mtx);
+#ifdef KSE
if (td->td_pflags & TDP_SA)
SIGADDSET(td->td_sigmask, sig);
+#endif
if (sig != newsig) {
ksiginfo_t ksi;
/*
@@ -2579,8 +2627,10 @@ issignal(td)
* signal is being masked, look for other signals.
*/
SIGADDSET(td->td_sigqueue.sq_signals, sig);
+#ifdef KSE
if (td->td_pflags & TDP_SA)
SIGDELSET(td->td_sigmask, sig);
+#endif
if (SIGISMEMBER(td->td_sigmask, sig))
continue;
signotify(td);
@@ -2743,7 +2793,11 @@ postsig(sig)
mtx_lock(&ps->ps_mtx);
}
+#ifdef KSE
if (!(td->td_pflags & TDP_SA) && action == SIG_DFL) {
+#else
+ if (action == SIG_DFL) {
+#endif
/*
* Default action, where the default is to kill
* the process. (Other cases were ignored above.)
@@ -2752,6 +2806,7 @@ postsig(sig)
sigexit(td, sig);
/* NOTREACHED */
} else {
+#ifdef KSE
if (td->td_pflags & TDP_SA) {
if (sig == SIGKILL) {
mtx_unlock(&ps->ps_mtx);
@@ -2759,6 +2814,7 @@ postsig(sig)
}
}
+#endif
/*
* If we get here, the signal must be caught.
*/
@@ -2801,10 +2857,14 @@ postsig(sig)
p->p_code = 0;
p->p_sig = 0;
}
+#ifdef KSE
if (td->td_pflags & TDP_SA)
thread_signal_add(curthread, &ksi);
else
(*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask);
+#else
+ (*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask);
+#endif
}
}