svn commit: r194834 - stable/7/sys/kern
John Baldwin
jhb at FreeBSD.org
Wed Jun 24 13:38:10 UTC 2009
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
More information about the svn-src-stable-7
mailing list