Wait for the real interval timer callout handler to finish executing if it
is currently executing when we try to remove it in exit1(). Without this, it was possible for the callout to bogusly rearm itself and eventually refire after the process had been free'd resulting in a panic. PR: kern/51964 Reported by: Jilles Tjoelker <jilles@stack.nl> Reviewed by: tegge, bde
This commit is contained in:
parent
8bccf7034e
commit
5499ea019d
@ -218,8 +218,18 @@ exit1(struct thread *td, int rv)
|
||||
p->p_flag &= ~(P_TRACED | P_PPWAIT);
|
||||
SIGEMPTYSET(p->p_siglist);
|
||||
SIGEMPTYSET(td->td_siglist);
|
||||
if (timevalisset(&p->p_realtimer.it_value))
|
||||
callout_stop(&p->p_itcallout);
|
||||
|
||||
/*
|
||||
* Stop the real interval timer. If the handler is currently
|
||||
* executing, prevent it from rearming itself and let it finish.
|
||||
*/
|
||||
if (timevalisset(&p->p_realtimer.it_value) &&
|
||||
callout_stop(&p->p_itcallout) == 0) {
|
||||
timevalclear(&p->p_realtimer.it_interval);
|
||||
msleep(&p->p_itcallout, &p->p_mtx, PWAIT, "ritwait", 0);
|
||||
KASSERT(!timevalisset(&p->p_realtimer.it_value),
|
||||
("realtime timer is still armed"));
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
/*
|
||||
|
@ -531,6 +531,8 @@ realitexpire(void *arg)
|
||||
psignal(p, SIGALRM);
|
||||
if (!timevalisset(&p->p_realtimer.it_interval)) {
|
||||
timevalclear(&p->p_realtimer.it_value);
|
||||
if (p->p_flag & P_WEXIT)
|
||||
wakeup(&p->p_itcallout);
|
||||
PROC_UNLOCK(p);
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user