From 627451c1d95f174a666b86394debbee99b9228b8 Mon Sep 17 00:00:00 2001 From: David Xu Date: Fri, 4 Mar 2005 22:46:31 +0000 Subject: [PATCH] The td_waitset is pointing to a stack address when thread is waiting for a signal, because kernel stack is swappable, this causes page fault in kernel under heavy swapping case. Fix this bug by eliminating unneeded code. --- sys/kern/kern_sig.c | 25 ++++++------------------- sys/sys/proc.h | 1 - 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 8caf77d547e..7928120f976 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -921,12 +921,10 @@ again: } else hz = 0; - td->td_waitset = &waitset; td->td_sigmask = savedmask; SIGSETNAND(td->td_sigmask, waitset); signotify(td); error = msleep(&ps, &p->p_mtx, PPAUSE|PCATCH, "sigwait", hz); - td->td_waitset = NULL; if (timeout) { if (error == ERESTART) { /* timeout can not be restarted. */ @@ -1577,28 +1575,17 @@ sigtd(struct proc *p, int sig, int prop) PROC_LOCK_ASSERT(p, MA_OWNED); /* - * First find a thread in sigwait state and signal belongs to - * its wait set. POSIX's arguments is that speed of delivering signal - * to sigwait thread is faster than delivering signal to user stack. - * If we can not find sigwait thread, then find the first thread in - * the proc that doesn't have this signal masked, an exception is - * if current thread is sending signal to its process, and it does not - * mask the signal, it should get the signal, this is another fast - * way to deliver signal. + * Check if current thread can handle the signal without + * switching conetxt to another thread. */ + if (curproc == p && !SIGISMEMBER(curthread->td_sigmask, sig)) + return (curthread); signal_td = NULL; mtx_lock_spin(&sched_lock); FOREACH_THREAD_IN_PROC(p, td) { - if (td->td_waitset != NULL && - SIGISMEMBER(*(td->td_waitset), sig)) { - mtx_unlock_spin(&sched_lock); - return (td); - } if (!SIGISMEMBER(td->td_sigmask, sig)) { - if (td == curthread) - signal_td = curthread; - else if (signal_td == NULL) - signal_td = td; + signal_td = td; + break; } } if (signal_td == NULL) diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 52b47efe4a2..ed476b3e84b 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -281,7 +281,6 @@ struct thread { sigset_t td_oldsigmask; /* (k) Saved mask from pre sigpause. */ sigset_t td_sigmask; /* (c) Current signal mask. */ sigset_t td_siglist; /* (c) Sigs arrived, not delivered. */ - sigset_t *td_waitset; /* (c) Wait set for sigwait. */ struct umtx_q *td_umtxq; /* (c?) Link for when we're blocked. */ volatile u_int td_generation; /* (k) For detection of preemption */ stack_t td_sigstk; /* (k) Stack ptr and on-stack flag. */