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-all mailing list