Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Jul 2008 10:53:25 GMT
From:      Ed Schouten <ed@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 145787 for review
Message-ID:  <200807241053.m6OArPwN029843@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145787

Change 145787 by ed@ed_dull on 2008/07/24 10:52:33

	Fixed to tty_wait() and tty_timedwait():
	
	- Make sure the TTY's lock has not been recursed yet. When a TTY
	  uses a lock that may be recursed, we cannot safely cv_wait()
	  on it.
	
	- Also add our Giant-workaround to tty_timedwait().

Affected files ...

.. //depot/projects/mpsafetty/sys/kern/tty.c#5 edit

Differences ...

==== //depot/projects/mpsafetty/sys/kern/tty.c#5 (text+ko) ====

@@ -1166,12 +1166,10 @@
 tty_wait(struct tty *tp, struct cv *cv)
 {
 	int error;
-	int revokecnt;
+	int revokecnt = tp->t_revokecnt;
 
-	tty_lock_assert(tp, MA_OWNED);
+	tty_lock_assert(tp, MA_OWNED|MA_NOTRECURSED);
 
-	/* Restart the system call when we may have been revoked */
-	revokecnt = tp->t_revokecnt;
 	if (tp->t_mtx == &Giant) {
 		/*
 		 * XXX: condvar(9) doesn't allow Giant to be passed as
@@ -1184,6 +1182,8 @@
 	} else {
 		error = cv_wait_sig(cv, tp->t_mtx);
 	}
+
+	/* Restart the system call when we may have been revoked */
 	if (tp->t_revokecnt != revokecnt)
 		return (ERESTART);
 	
@@ -1198,13 +1198,25 @@
 tty_timedwait(struct tty *tp, struct cv *cv, int hz)
 {
 	int error;
-	int revokecnt;
+	int revokecnt = tp->t_revokecnt;
+
+	tty_lock_assert(tp, MA_OWNED|MA_NOTRECURSED);
 
-	tty_lock_assert(tp, MA_OWNED);
+	error = cv_timedwait_sig(cv, tp->t_mtx, hz);
+	if (tp->t_mtx == &Giant) {
+		/*
+		 * XXX: condvar(9) doesn't allow Giant to be passed as
+		 * its mutex. Because we don't use the per-TTY mutex
+		 * here, temporarily abuse it to make condvar(9) work.
+		 */
+		mtx_lock(&tp->t_mtxobj);
+		error = cv_timedwait_sig(cv, &tp->t_mtxobj, hz);
+		mtx_unlock(&tp->t_mtxobj);
+	} else {
+		error = cv_timedwait_sig(cv, tp->t_mtx, hz);
+	}
 
 	/* Restart the system call when we may have been revoked */
-	revokecnt = tp->t_revokecnt;
-	error = cv_timedwait_sig(cv, tp->t_mtx, hz);
 	if (tp->t_revokecnt != revokecnt)
 		return (ERESTART);
 	



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807241053.m6OArPwN029843>