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.
This commit is contained in:
parent
6d93d4fb04
commit
627451c1d9
@ -921,12 +921,10 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, siginfo_t *info,
|
||||
} 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)
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user