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>