Properly fix the "hanging in tty" bug that was worked around with cv_wakeup()

some time again.
This commit is contained in:
ad 2008-05-25 19:22:21 +00:00
parent b26c8099ce
commit 5e4b324300
13 changed files with 73 additions and 74 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mfc.c,v 1.48 2007/11/19 18:51:37 ad Exp $ */
/* $NetBSD: mfc.c,v 1.49 2008/05/25 19:22:21 ad Exp $ */
/*
* Copyright (c) 1982, 1990 The Regents of the University of California.
@ -55,7 +55,7 @@
#include "opt_kgdb.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mfc.c,v 1.48 2007/11/19 18:51:37 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: mfc.c,v 1.49 2008/05/25 19:22:21 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -546,7 +546,7 @@ mfcsopen(dev_t dev, int flag, int mode, struct lwp *l)
*/
while ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0) {
tp->t_wopen++;
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
tp->t_wopen--;
if (error) {
mutex_spin_exit(&tty_lock);

View File

@ -1,4 +1,4 @@
/* $NetBSD: msc.c,v 1.40 2007/11/19 18:51:37 ad Exp $ */
/* $NetBSD: msc.c,v 1.41 2008/05/25 19:22:21 ad Exp $ */
/*
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
@ -93,7 +93,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msc.c,v 1.40 2007/11/19 18:51:37 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: msc.c,v 1.41 2008/05/25 19:22:21 ad Exp $");
#include "msc.h"
@ -438,7 +438,7 @@ mscopen(dev_t dev, int flag, int mode, struct lwp *l)
#if DEBUG_CD
printf("msc%d: %d waiting for CD\n", msc->unit, MSCLINE(dev));
#endif
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
tp->t_wopen--;
if (error) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: sab.c,v 1.40 2007/11/28 18:04:33 ad Exp $ */
/* $NetBSD: sab.c,v 1.41 2008/05/25 19:22:21 ad Exp $ */
/* $OpenBSD: sab.c,v 1.7 2002/04/08 17:49:42 jason Exp $ */
/*
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sab.c,v 1.40 2007/11/28 18:04:33 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: sab.c,v 1.41 2008/05/25 19:22:21 ad Exp $");
#include "opt_kgdb.h"
#include <sys/types.h>
@ -717,7 +717,7 @@ sabopen(dev_t dev, int flags, int mode, struct lwp *l)
(tp->t_state & TS_CARR_ON) == 0) {
int error;
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
if (error != 0) {
mutex_spin_exit(&tty_lock);
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: dz.c,v 1.35 2008/03/15 00:57:15 matt Exp $ */
/* $NetBSD: dz.c,v 1.36 2008/05/25 19:22:21 ad Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: dz.c,v 1.35 2008/03/15 00:57:15 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: dz.c,v 1.36 2008/05/25 19:22:21 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -401,7 +401,7 @@ dzopen(dev_t dev, int flag, int mode, struct lwp *l)
while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&
!(tp->t_state & TS_CARR_ON)) {
tp->t_wopen++;
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
tp->t_wopen--;
if (error)
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cy.c,v 1.55 2008/03/26 17:50:32 matt Exp $ */
/* $NetBSD: cy.c,v 1.56 2008/05/25 19:22:21 ad Exp $ */
/*
* cy.c
@ -16,7 +16,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cy.c,v 1.55 2008/03/26 17:50:32 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: cy.c,v 1.56 2008/05/25 19:22:21 ad Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
@ -391,7 +391,7 @@ cyopen(dev_t dev, int flag, int mode, struct lwp *l)
while (!ISSET(tp->t_cflag, CLOCAL) &&
!ISSET(tp->t_state, TS_CARR_ON)) {
tp->t_wopen++;
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
tp->t_wopen--;
if (error != 0) {
mutex_spin_exit(&tty_lock);

View File

@ -1,4 +1,4 @@
/* $NetBSD: irframe_tty.c,v 1.53 2008/04/28 20:23:51 martin Exp $ */
/* $NetBSD: irframe_tty.c,v 1.54 2008/05/25 19:22:21 ad Exp $ */
/*
* TODO
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irframe_tty.c,v 1.53 2008/04/28 20:23:51 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: irframe_tty.c,v 1.54 2008/05/25 19:22:21 ad Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@ -654,7 +654,7 @@ irt_putc(struct tty *tp, int c)
mutex_spin_exit(&tty_lock);
goto go;
}
error = ttysleep(tp, &tp->t_outq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_outcv, true, 0);
mutex_spin_exit(&tty_lock);
if (error)
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: dhu.c,v 1.52 2008/03/11 05:34:01 matt Exp $ */
/* $NetBSD: dhu.c,v 1.53 2008/05/25 19:22:21 ad Exp $ */
/*
* Copyright (c) 2003, Hugh Graham.
* Copyright (c) 1992, 1993
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: dhu.c,v 1.52 2008/03/11 05:34:01 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: dhu.c,v 1.53 2008/05/25 19:22:21 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -476,7 +476,7 @@ dhuopen(dev_t dev, int flag, int mode, struct lwp *l)
while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&
!(tp->t_state & TS_CARR_ON)) {
tp->t_wopen++;
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
tp->t_wopen--;
if (error)
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: spif.c,v 1.15 2008/04/05 18:35:32 cegger Exp $ */
/* $NetBSD: spif.c,v 1.16 2008/05/25 19:22:21 ad Exp $ */
/* $OpenBSD: spif.c,v 1.12 2003/10/03 16:44:51 miod Exp $ */
/*
@ -41,7 +41,7 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: spif.c,v 1.15 2008/04/05 18:35:32 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: spif.c,v 1.16 2008/05/25 19:22:21 ad Exp $");
#include "spif.h"
#if NSPIF > 0
@ -391,7 +391,7 @@ stty_open(dev, flags, mode, l)
while (!ISSET(tp->t_cflag, CLOCAL) &&
!ISSET(tp->t_state, TS_CARR_ON)) {
int error;
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
if (error != 0) {
mutex_spin_exit(&tty_lock);
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.223 2008/05/03 05:34:23 yamt Exp $ */
/* $NetBSD: tty.c,v 1.224 2008/05/25 19:22:21 ad Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.223 2008/05/03 05:34:23 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.224 2008/05/25 19:22:21 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -275,7 +275,7 @@ ttyopen(struct tty *tp, int dialout, int nonblock)
while (ISSET(tp->t_state, TS_DIALOUT) ||
!CONNECTED(tp)) {
tp->t_wopen++;
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
tp->t_wopen--;
if (error)
goto out;
@ -1412,7 +1412,7 @@ ttywait(struct tty *tp)
while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
CONNECTED(tp) && tp->t_oproc) {
(*tp->t_oproc)(tp);
error = ttysleep(tp, &tp->t_outq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_outcv, true, 0);
if (error)
break;
}
@ -1459,7 +1459,7 @@ ttyflush(struct tty *tp, int rw)
CLR(tp->t_state, TS_TTSTOP);
cdev_stop(tp, rw);
FLUSHQ(&tp->t_outq);
clwakeup(&tp->t_outq);
cv_broadcast(&tp->t_outcv);
selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
}
}
@ -1787,7 +1787,7 @@ ttread(struct tty *tp, struct uio *uio, int flag)
mutex_spin_exit(&tty_lock);
return (EWOULDBLOCK);
}
error = ttysleep(tp, &tp->t_rawq.c_cv, true, slp);
error = ttysleep(tp, &tp->t_rawcv, true, slp);
mutex_spin_exit(&tty_lock);
/* VMIN == 0: any quantity read satisfies */
if (cc[VMIN] == 0 && error == EWOULDBLOCK)
@ -1885,7 +1885,7 @@ ttycheckoutq_wlock(struct tty *tp, int wait)
ttstart(tp);
if (wait == 0)
return (0);
error = ttysleep(tp, &tp->t_outq.c_cv, true, hz);
error = ttysleep(tp, &tp->t_outcv, true, hz);
if (error == EINTR)
wait = 0;
}
@ -1934,7 +1934,7 @@ ttwrite(struct tty *tp, struct uio *uio, int flag)
goto out;
} else {
/* Sleep awaiting carrier. */
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
mutex_spin_exit(&tty_lock);
if (error)
goto out;
@ -2092,7 +2092,7 @@ ttwrite(struct tty *tp, struct uio *uio, int flag)
error = EWOULDBLOCK;
goto out;
}
error = ttysleep(tp, &tp->t_outq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_outcv, true, 0);
mutex_spin_exit(&tty_lock);
if (error)
goto out;
@ -2110,7 +2110,7 @@ ttypull(struct tty *tp)
/* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
if (tp->t_outq.c_cc <= tp->t_lowat) {
clwakeup(&tp->t_outq);
cv_broadcast(&tp->t_outcv);
selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
}
return tp->t_outq.c_cc != 0;
@ -2285,12 +2285,7 @@ ttwakeup(struct tty *tp)
selnotify(&tp->t_rsel, 0, NOTE_SUBMIT);
if (ISSET(tp->t_state, TS_ASYNC))
ttysig(tp, TTYSIG_PG2, SIGIO);
#if 0
/* XXX tp->t_rawq.c_cv.cv_waiters dropping to zero early!? */
clwakeup(&tp->t_rawq);
#else
cv_wakeup(&tp->t_rawq.c_cv);
#endif
cv_broadcast(&tp->t_rawcv);
}
/*
@ -2637,9 +2632,15 @@ ttymalloc(void)
callout_setfunc(&tp->t_rstrt_ch, ttrstrt, tp);
/* XXX: default to 1024 chars for now */
clalloc(&tp->t_rawq, 1024, 1);
cv_init(&tp->t_rawcv, "ttyraw");
cv_init(&tp->t_rawcvf, "ttyrawf");
clalloc(&tp->t_canq, 1024, 1);
cv_init(&tp->t_cancv, "ttycan");
cv_init(&tp->t_cancvf, "ttycanf");
/* output queue doesn't need quoting */
clalloc(&tp->t_outq, 1024, 0);
cv_init(&tp->t_outcv, "ttycan");
cv_init(&tp->t_outcvf, "ttycanf");
/* Set default line discipline. */
tp->t_linesw = ttyldisc_default();
selinit(&tp->t_rsel);
@ -2675,6 +2676,12 @@ ttyfree(struct tty *tp)
clfree(&tp->t_rawq);
clfree(&tp->t_canq);
clfree(&tp->t_outq);
cv_destroy(&tp->t_rawcv);
cv_destroy(&tp->t_rawcvf);
cv_destroy(&tp->t_cancv);
cv_destroy(&tp->t_cancvf);
cv_destroy(&tp->t_outcv);
cv_destroy(&tp->t_outcvf);
seldestroy(&tp->t_rsel);
seldestroy(&tp->t_wsel);
kmem_free(tp, sizeof(*tp));

View File

@ -1,4 +1,4 @@
/* $NetBSD: tty_pty.c,v 1.109 2008/04/20 19:22:45 ad Exp $ */
/* $NetBSD: tty_pty.c,v 1.110 2008/05/25 19:22:21 ad Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tty_pty.c,v 1.109 2008/04/20 19:22:45 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: tty_pty.c,v 1.110 2008/05/25 19:22:21 ad Exp $");
#include "opt_compat_sunos.h"
#include "opt_ptm.h"
@ -344,7 +344,7 @@ ptsopen(dev_t dev, int flag, int devtype, struct lwp *l)
if (!ISSET(flag, O_NONBLOCK)) {
while (!ISSET(tp->t_state, TS_CARR_ON)) {
tp->t_wopen++;
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
tp->t_wopen--;
if (error) {
mutex_spin_exit(&tty_lock);
@ -405,7 +405,7 @@ again:
mutex_spin_exit(&tty_lock);
return (EWOULDBLOCK);
}
error = ttysleep(tp, &tp->t_canq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_cancv, true, 0);
mutex_spin_exit(&tty_lock);
if (error)
return (error);
@ -487,7 +487,7 @@ ptsstart(tp)
}
selnotify(&pti->pt_selr, 0, NOTE_SUBMIT);
cv_broadcast(&tp->t_outq.c_cvf);
cv_broadcast(&tp->t_outcvf);
}
/*
@ -513,11 +513,11 @@ ptsstop(tp, flush)
/* change of perspective */
if (flush & FREAD) {
selnotify(&pti->pt_selw, 0, NOTE_SUBMIT);
cv_broadcast(&tp->t_rawq.c_cvf);
cv_broadcast(&tp->t_rawcvf);
}
if (flush & FWRITE) {
selnotify(&pti->pt_selr, 0, NOTE_SUBMIT);
cv_broadcast(&tp->t_outq.c_cvf);
cv_broadcast(&tp->t_outcvf);
}
}
@ -531,11 +531,11 @@ ptcwakeup(tp, flag)
mutex_spin_enter(&tty_lock);
if (flag & FREAD) {
selnotify(&pti->pt_selr, 0, NOTE_SUBMIT);
cv_broadcast(&tp->t_outq.c_cvf);
cv_broadcast(&tp->t_outcvf);
}
if (flag & FWRITE) {
selnotify(&pti->pt_selw, 0, NOTE_SUBMIT);
cv_broadcast(&tp->t_rawq.c_cvf);
cv_broadcast(&tp->t_rawcvf);
}
mutex_spin_exit(&tty_lock);
}
@ -644,7 +644,7 @@ ptcread(dev, uio, flag)
error = EWOULDBLOCK;
goto out;
}
error = cv_wait_sig(&tp->t_outq.c_cvf, &tty_lock);
error = cv_wait_sig(&tp->t_outcvf, &tty_lock);
if (error)
goto out;
}
@ -721,7 +721,7 @@ again:
}
(void) putc(0, &tp->t_canq);
ttwakeup(tp);
clwakeup(&tp->t_canq);
cv_broadcast(&tp->t_cancv);
error = 0;
goto out;
}
@ -745,7 +745,7 @@ again:
while (cc > 0) {
if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
(tp->t_canq.c_cc > 0 || !ISSET(tp->t_lflag, ICANON))) {
clwakeup(&tp->t_rawq);
cv_broadcast(&tp->t_rawcv);
goto block;
}
/* XXX - should change l_rint to be called with lock
@ -779,7 +779,7 @@ block:
error = cnt == 0 ? EWOULDBLOCK : 0;
goto out;
}
error = cv_wait_sig(&tp->t_rawq.c_cv, &tty_lock);
error = cv_wait_sig(&tp->t_rawcv, &tty_lock);
mutex_spin_exit(&tty_lock);
if (error) {
/* adjust for data copied in but not written */

View File

@ -1,4 +1,4 @@
/* $NetBSD: tty_subr.c,v 1.32 2007/12/22 02:21:29 ad Exp $ */
/* $NetBSD: tty_subr.c,v 1.33 2008/05/25 19:22:21 ad Exp $ */
/*
* Copyright (c) 1993, 1994 Theo de Raadt
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tty_subr.c,v 1.32 2007/12/22 02:21:29 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: tty_subr.c,v 1.33 2008/05/25 19:22:21 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -93,8 +93,6 @@ clalloc(struct clist *clp, int size, int quot)
clp->c_cn = size;
clp->c_cc = 0;
cv_init(&clp->c_cv, "tty");
cv_init(&clp->c_cvf, "ttyf");
return (0);
}
@ -106,15 +104,6 @@ clfree(struct clist *clp)
if(clp->c_cq)
free(clp->c_cq, M_TTYS);
clp->c_cs = clp->c_cq = (u_char *)0;
cv_destroy(&clp->c_cv);
cv_destroy(&clp->c_cvf);
}
void
clwakeup(struct clist *clp)
{
cv_broadcast(&clp->c_cv);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: ppp_tty.c,v 1.52 2008/02/20 17:05:53 matt Exp $ */
/* $NetBSD: ppp_tty.c,v 1.53 2008/05/25 19:22:21 ad Exp $ */
/* Id: ppp_tty.c,v 1.3 1996/07/01 01:04:11 paulus Exp */
/*
@ -93,7 +93,7 @@
/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ppp_tty.c,v 1.52 2008/02/20 17:05:53 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: ppp_tty.c,v 1.53 2008/05/25 19:22:21 ad Exp $");
#include "ppp.h"
@ -352,7 +352,7 @@ pppread(struct tty *tp, struct uio *uio, int flag)
mutex_spin_exit(&tty_lock);
return (EWOULDBLOCK);
}
error = ttysleep(tp, &tp->t_rawq.c_cv, true, 0);
error = ttysleep(tp, &tp->t_rawcv, true, 0);
if (error) {
mutex_spin_exit(&tty_lock);
return error;

View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.h,v 1.81 2008/04/28 20:24:11 martin Exp $ */
/* $NetBSD: tty.h,v 1.82 2008/05/25 19:22:21 ad Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -87,8 +87,6 @@ struct clist {
u_char *c_cs; /* start of ring buffer */
u_char *c_ce; /* c_ce + c_len */
u_char *c_cq; /* N bits/bytes long, see tty_subr.c */
kcondvar_t c_cv; /* notifier, locked by tty lock */
kcondvar_t c_cvf; /* notifier, locked by tty lock */
int c_cc; /* count of characters in queue */
int c_cn; /* total ring buffer length */
};
@ -112,11 +110,17 @@ struct tty {
TAILQ_ENTRY(tty) tty_link; /* Link in global tty list. */
struct clist t_rawq; /* Device raw input queue. */
long t_rawcc; /* Raw input queue statistics. */
kcondvar_t t_rawcv; /* notifier */
kcondvar_t t_rawcvf; /* notifier */
struct clist t_canq; /* Device canonical queue. */
long t_cancc; /* Canonical queue statistics. */
kcondvar_t t_cancv; /* notifier */
kcondvar_t t_cancvf; /* notifier */
struct clist t_outq; /* Device output queue. */
callout_t t_rstrt_ch; /* for delayed output start */
long t_outcc; /* Output queue statistics. */
kcondvar_t t_outcv; /* notifier */
kcondvar_t t_outcvf; /* notifier */
callout_t t_rstrt_ch; /* for delayed output start */
struct linesw *t_linesw; /* Interface to device drivers. */
dev_t t_dev; /* Device. */
int t_state; /* Device and driver (TS*) state. */
@ -294,7 +298,6 @@ bool ttypull(struct tty *);
int clalloc(struct clist *, int, int);
void clfree(struct clist *);
void clwakeup(struct clist *);
#if defined(_KERNEL_OPT)
#include "opt_compat_freebsd.h"