Date: Wed, 24 Jun 2009 13:38:08 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r194834 - stable/7/sys/kern Message-ID: <200906241338.n5ODc8R6015827@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Wed Jun 24 13:38:08 2009 New Revision: 194834 URL: http://svn.freebsd.org/changeset/base/194834 Log: Defer the wakeup of the swapper process to the callers of tdsigwakeup() to avoid a deadlock since the thread lock isn't released until after tdsigwakeup() has returned. This is a direct commit instead of an MFC as this issue was fixed in HEAD by a much larger set of changes that are not suitable for MFC. Modified: stable/7/sys/kern/kern_sig.c Modified: stable/7/sys/kern/kern_sig.c ============================================================================== --- stable/7/sys/kern/kern_sig.c Wed Jun 24 13:36:37 2009 (r194833) +++ stable/7/sys/kern/kern_sig.c Wed Jun 24 13:38:08 2009 (r194834) @@ -88,7 +88,7 @@ static char *expand_name(const char *, u static int killpg1(struct thread *td, int sig, int pgid, int all); static int issignal(struct thread *p); static int sigprop(int sig); -static void tdsigwakeup(struct thread *, int, sig_t, int); +static int tdsigwakeup(struct thread *, int, sig_t, int); static void sig_suspend_threads(struct thread *, struct proc *, int); static int filt_sigattach(struct knote *kn); static void filt_sigdetach(struct knote *kn); @@ -2289,9 +2289,11 @@ do_tdsignal(struct proc *p, struct threa } else if (p->p_state == PRS_NORMAL) { if (p->p_flag & P_TRACED || action == SIG_CATCH) { thread_lock(td); - tdsigwakeup(td, sig, action, intrval); + wakeup_swapper = tdsigwakeup(td, sig, action, intrval); thread_unlock(td); PROC_SUNLOCK(p); + if (wakeup_swapper) + kick_proc0(); goto out; } @@ -2337,10 +2339,12 @@ do_tdsignal(struct proc *p, struct threa runfast: thread_lock(td); - tdsigwakeup(td, sig, action, intrval); + wakeup_swapper = tdsigwakeup(td, sig, action, intrval); thread_unlock(td); thread_unsuspend(p); PROC_SUNLOCK(p); + if (wakeup_swapper) + kick_proc0(); out: /* If we jump here, proc slock should not be owned. */ PROC_SLOCK_ASSERT(p, MA_NOTOWNED); @@ -2352,7 +2356,7 @@ out: * thread. We need to see what we can do about knocking it * out of any sleep it may be in etc. */ -static void +static int tdsigwakeup(struct thread *td, int sig, sig_t action, int intrval) { struct proc *p = td->td_proc; @@ -2380,7 +2384,7 @@ tdsigwakeup(struct thread *td, int sig, * trap() or syscall(). */ if ((td->td_flags & TDF_SINTR) == 0) - return; + return (0); /* * If SIGCONT is default (or ignored) and process is * asleep, we are finished; the process should not @@ -2397,7 +2401,7 @@ tdsigwakeup(struct thread *td, int sig, sigqueue_delete(&td->td_sigqueue, sig); PROC_SLOCK(p); thread_lock(td); - return; + return (0); } /* @@ -2418,8 +2422,7 @@ tdsigwakeup(struct thread *td, int sig, forward_signal(td); #endif } - if (wakeup_swapper) - kick_proc0(); + return (wakeup_swapper); } static void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906241338.n5ODc8R6015827>