Module Name: src Committed By: riastradh Date: Fri Oct 7 18:59:37 UTC 2022
Modified Files: src/sys/dev: cons.c src/sys/kern: subr_prf.c tty.c src/sys/sys: tty.h Log Message: Revert "constty(4): Make MP-safe." Something is still busted and this is interfering with the releng amd64 testbed. To generate a diff of this commit: cvs rdiff -u -r1.89 -r1.90 src/sys/dev/cons.c cvs rdiff -u -r1.192 -r1.193 src/sys/kern/subr_prf.c cvs rdiff -u -r1.304 -r1.305 src/sys/kern/tty.c cvs rdiff -u -r1.100 -r1.101 src/sys/sys/tty.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/cons.c diff -u src/sys/dev/cons.c:1.89 src/sys/dev/cons.c:1.90 --- src/sys/dev/cons.c:1.89 Fri Oct 7 18:55:50 2022 +++ src/sys/dev/cons.c Fri Oct 7 18:59:37 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: cons.c,v 1.89 2022/10/07 18:55:50 riastradh Exp $ */ +/* $NetBSD: cons.c,v 1.90 2022/10/07 18:59:37 riastradh Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cons.c,v 1.89 2022/10/07 18:55:50 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cons.c,v 1.90 2022/10/07 18:59:37 riastradh Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -54,8 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: cons.c,v 1.8 #include <sys/kauth.h> #include <sys/mutex.h> #include <sys/module.h> -#include <sys/atomic.h> -#include <sys/pserialize.h> #include <dev/cons.h> @@ -69,8 +67,7 @@ dev_type_ioctl(cnioctl); dev_type_poll(cnpoll); dev_type_kqfilter(cnkqfilter); -static bool cn_redirect(dev_t *, int, int *, struct tty **); -static void cn_release(struct tty *); +static bool cn_redirect(dev_t *, int, int *); const struct cdevsw cons_cdevsw = { .d_open = cnopen, @@ -89,7 +86,7 @@ const struct cdevsw cons_cdevsw = { static struct kmutex cn_lock; -struct tty *volatile constty; /* virtual console output device */ +struct tty *constty = NULL; /* virtual console output device */ struct consdev *cn_tab; /* physical console device info */ struct vnode *cn_devvp[2]; /* vnode for underlying device. */ @@ -202,7 +199,6 @@ out: mutex_exit(&cn_lock); int cnread(dev_t dev, struct uio *uio, int flag) { - struct tty *ctp = NULL; int error; /* @@ -212,31 +208,25 @@ cnread(dev_t dev, struct uio *uio, int f * input (except a shell in single-user mode, but then, * one wouldn't TIOCCONS then). */ - if (!cn_redirect(&dev, 1, &error, &ctp)) + if (!cn_redirect(&dev, 1, &error)) return error; - error = cdev_read(dev, uio, flag); - cn_release(ctp); - return error; + return cdev_read(dev, uio, flag); } int cnwrite(dev_t dev, struct uio *uio, int flag) { - struct tty *ctp = NULL; int error; /* Redirect output, if that's appropriate. */ - if (!cn_redirect(&dev, 0, &error, &ctp)) + if (!cn_redirect(&dev, 0, &error)) return error; - error = cdev_write(dev, uio, flag); - cn_release(ctp); - return error; + return cdev_write(dev, uio, flag); } int cnioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { - struct tty *ctp = NULL; int error; error = 0; @@ -245,41 +235,29 @@ cnioctl(dev_t dev, u_long cmd, void *dat * Superuser can always use this to wrest control of console * output from the "virtual" console. */ - if (cmd == TIOCCONS) { - struct tty *tp; - - mutex_enter(&constty_lock); - tp = atomic_load_relaxed(&constty); - if (tp == NULL) { - mutex_exit(&constty_lock); - goto passthrough; /* XXX ??? */ - } + if (cmd == TIOCCONS && constty != NULL) { error = kauth_authorize_device_tty(l->l_cred, - KAUTH_DEVICE_TTY_VIRTUAL, tp); + KAUTH_DEVICE_TTY_VIRTUAL, constty); if (!error) - atomic_store_relaxed(&constty, NULL); - mutex_exit(&constty_lock); - return error; + constty = NULL; + return (error); } -passthrough: + /* * Redirect the ioctl, if that's appropriate. * Note that strange things can happen, if a program does * ioctls on /dev/console, then the console is redirected * out from under it. */ - if (!cn_redirect(&dev, 0, &error, &ctp)) + if (!cn_redirect(&dev, 0, &error)) return error; - error = cdev_ioctl(dev, cmd, data, flag, l); - cn_release(ctp); - return error; + return cdev_ioctl(dev, cmd, data, flag, l); } /*ARGSUSED*/ int cnpoll(dev_t dev, int events, struct lwp *l) { - struct tty *ctp = NULL; int error; /* @@ -287,18 +265,15 @@ cnpoll(dev_t dev, int events, struct lwp * I don't want to think of the possible side effects * of console redirection here. */ - if (!cn_redirect(&dev, 0, &error, &ctp)) + if (!cn_redirect(&dev, 0, &error)) return POLLHUP; - error = cdev_poll(dev, events, l); - cn_release(ctp); - return error; + return cdev_poll(dev, events, l); } /*ARGSUSED*/ int cnkqfilter(dev_t dev, struct knote *kn) { - struct tty *ctp = NULL; int error; /* @@ -306,11 +281,9 @@ cnkqfilter(dev_t dev, struct knote *kn) * I don't want to think of the possible side effects * of console redirection here. */ - if (!cn_redirect(&dev, 0, &error, &ctp)) + if (!cn_redirect(&dev, 0, &error)) return error; - error = cdev_kqfilter(dev, kn); - cn_release(ctp); - return error; + return cdev_kqfilter(dev, kn); } int @@ -456,44 +429,28 @@ cnhalt(void) /* * Redirect output, if that's appropriate. If there's no real console, * return ENXIO. + * + * Call with tty_mutex held. */ static bool -cn_redirect(dev_t *devp, int is_read, int *error, struct tty **ctpp) +cn_redirect(dev_t *devp, int is_read, int *error) { dev_t dev = *devp; - struct tty *ctp; - int s; - bool ok = false; *error = ENXIO; - *ctpp = NULL; - s = pserialize_read_enter(); - if ((ctp = atomic_load_consume(&constty)) != NULL && minor(dev) == 0 && + if (constty != NULL && minor(dev) == 0 && (cn_tab == NULL || (cn_tab->cn_pri != CN_REMOTE))) { if (is_read) { *error = 0; - goto out; + return false; } - tty_acquire(ctp); - *ctpp = ctp; - dev = ctp->t_dev; + dev = constty->t_dev; } else if (cn_tab == NULL) - goto out; + return false; else dev = cn_tab->cn_dev; - ok = true; *devp = dev; -out: pserialize_read_exit(s); - return ok; -} - -static void -cn_release(struct tty *ctp) -{ - - if (ctp == NULL) - return; - tty_release(ctp); + return true; } MODULE(MODULE_CLASS_DRIVER, cons, NULL); Index: src/sys/kern/subr_prf.c diff -u src/sys/kern/subr_prf.c:1.192 src/sys/kern/subr_prf.c:1.193 --- src/sys/kern/subr_prf.c:1.192 Thu Oct 6 19:58:41 2022 +++ src/sys/kern/subr_prf.c Fri Oct 7 18:59:37 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_prf.c,v 1.192 2022/10/06 19:58:41 riastradh Exp $ */ +/* $NetBSD: subr_prf.c,v 1.193 2022/10/07 18:59:37 riastradh Exp $ */ /*- * Copyright (c) 1986, 1988, 1991, 1993 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.192 2022/10/06 19:58:41 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.193 2022/10/07 18:59:37 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -103,6 +103,7 @@ static void kprintf_internal(const char * globals */ +extern struct tty *constty; /* pointer to console "window" tty */ extern int log_open; /* subr_log: is /dev/klog open? */ const char *panicstr; /* arg to first call to panic (used as a flag to indicate that panic has already been called). */ @@ -400,35 +401,22 @@ addlog(const char *fmt, ...) static void putone(int c, int flags, struct tty *tp) { - struct tty *ctp; - int s; - - /* - * Ensure whatever constty points to can't go away while we're - * trying to use it. - */ - s = pserialize_read_enter(); - if (panicstr) - atomic_store_relaxed(&constty, NULL); + constty = NULL; - if ((flags & TOCONS) && - (ctp = atomic_load_consume(&constty)) != NULL && - tp == NULL) { - tp = ctp; + if ((flags & TOCONS) && tp == NULL && constty) { + tp = constty; flags |= TOTTY; } if ((flags & TOTTY) && tp && tputchar(c, flags, tp) < 0 && - (flags & TOCONS)) - atomic_cas_ptr(&constty, tp, NULL); + (flags & TOCONS) && tp == constty) + constty = NULL; if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177) logputchar(c); - if ((flags & TOCONS) && ctp == NULL && c != '\0') + if ((flags & TOCONS) && constty == NULL && c != '\0') (*v_putc)(c); - - pserialize_read_exit(s); } static void Index: src/sys/kern/tty.c diff -u src/sys/kern/tty.c:1.304 src/sys/kern/tty.c:1.305 --- src/sys/kern/tty.c:1.304 Thu Oct 6 19:58:41 2022 +++ src/sys/kern/tty.c Fri Oct 7 18:59:37 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.304 2022/10/06 19:58:41 riastradh Exp $ */ +/* $NetBSD: tty.c,v 1.305 2022/10/07 18:59:37 riastradh Exp $ */ /*- * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.304 2022/10/06 19:58:41 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.305 2022/10/07 18:59:37 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -99,9 +99,6 @@ __KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.30 #include <sys/module.h> #include <sys/bitops.h> #include <sys/compat_stub.h> -#include <sys/atomic.h> -#include <sys/condvar.h> -#include <sys/pserialize.h> #ifdef COMPAT_60 #include <compat/sys/ttycom.h> @@ -212,9 +209,6 @@ static void *tty_sigsih; struct ttylist_head ttylist = TAILQ_HEAD_INITIALIZER(ttylist); int tty_count; kmutex_t tty_lock; -kmutex_t constty_lock; -static struct pserialize *constty_psz; -static kcondvar_t ttyref_cv; struct ptm_pty *ptm = NULL; @@ -448,29 +442,14 @@ ttycancel(struct tty *tp) int ttyclose(struct tty *tp) { + extern struct tty *constty; /* Temporary virtual console. */ struct session *sess; - /* - * Make sure this is not the constty. Without constty_lock it - * is always allowed to transition from nonnull to null. - */ - (void)atomic_cas_ptr(&constty, tp, NULL); - - /* - * We don't know if this has _ever_ been the constty: another - * thread may have kicked it out as constty before we started - * to close. - * - * So we wait for all users that might be acquiring references - * to finish doing so -- after that, no more references can be - * made, at which point we can safely flush the tty, wait for - * the existing references to drain, and finally free or reuse - * the tty. - */ - pserialize_perform(constty_psz); - mutex_spin_enter(&tty_lock); + if (constty == tp) + constty = NULL; + ttyflush(tp, FREAD | FWRITE); tp->t_gen++; @@ -479,9 +458,6 @@ ttyclose(struct tty *tp) sess = tp->t_session; tp->t_session = NULL; - while (tp->t_refcnt) - cv_wait(&ttyref_cv, &tty_lock); - mutex_spin_exit(&tty_lock); if (sess != NULL) { @@ -498,44 +474,6 @@ ttyclose(struct tty *tp) } /* - * tty_acquire(tp), tty_release(tp) - * - * Acquire a reference to tp that prevents it from being closed - * until released. Caller must guarantee tp has not yet been - * closed, e.g. by obtaining tp from constty during a pserialize - * read section. Caller must not hold tty_lock. - */ -void -tty_acquire(struct tty *tp) -{ - unsigned refcnt __diagused; - - refcnt = atomic_inc_uint_nv(&tp->t_refcnt); - KASSERT(refcnt < UINT_MAX); -} - -void -tty_release(struct tty *tp) -{ - unsigned old, new; - - KDASSERT(mutex_ownable(&tty_lock)); - - do { - old = atomic_load_relaxed(&tp->t_refcnt); - if (old == 1) { - mutex_spin_enter(&tty_lock); - if (atomic_dec_uint_nv(&tp->t_refcnt) == 0) - cv_broadcast(&ttyref_cv); - mutex_spin_exit(&tty_lock); - return; - } - KASSERT(old != 0); - new = old - 1; - } while (atomic_cas_uint(&tp->t_refcnt, old, new) != old); -} - -/* * This macro is used in canonical mode input processing, where a read * request shall not return unless a 'line delimiter' ('\n') or 'break' * (EOF, EOL, EOL2) character (or a signal) has been received. As EOL2 @@ -1003,6 +941,7 @@ ttyoutput(int c, struct tty *tp) int ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l) { + extern struct tty *constty; /* Temporary virtual console. */ struct proc *p; struct linesw *lp; int s, error; @@ -1105,47 +1044,32 @@ ttioctl(struct tty *tp, u_long cmd, void mutex_spin_exit(&tty_lock); break; } - case TIOCCONS: { /* become virtual console */ - struct tty *ctp; - - mutex_enter(&constty_lock); - error = 0; - ctp = atomic_load_relaxed(&constty); + case TIOCCONS: /* become virtual console */ if (*(int *)data) { - if (ctp != NULL && ctp != tp && - ISSET(ctp->t_state, TS_CARR_ON | TS_ISOPEN) == - (TS_CARR_ON | TS_ISOPEN)) { - error = EBUSY; - goto unlock_constty; - } + if (constty && constty != tp && + ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) == + (TS_CARR_ON | TS_ISOPEN)) + return EBUSY; pb = pathbuf_create("/dev/console"); if (pb == NULL) { - error = ENOMEM; - goto unlock_constty; + return ENOMEM; } NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, pb); if ((error = namei(&nd)) != 0) { pathbuf_destroy(pb); - goto unlock_constty; + return error; } error = VOP_ACCESS(nd.ni_vp, VREAD, l->l_cred); vput(nd.ni_vp); pathbuf_destroy(pb); if (error) - goto unlock_constty; + return error; - KASSERT(atomic_load_relaxed(&constty) == ctp || - atomic_load_relaxed(&constty) == NULL); - atomic_store_release(&constty, tp); - } else if (tp == ctp) { - atomic_store_relaxed(&constty, NULL); - } -unlock_constty: mutex_exit(&constty_lock); - if (error) - return error; + constty = tp; + } else if (tp == constty) + constty = NULL; break; - } case TIOCDRAIN: /* wait till output drained */ if ((error = ttywait(tp)) != 0) return (error); @@ -3044,8 +2968,6 @@ tty_init(void) { mutex_init(&tty_lock, MUTEX_DEFAULT, IPL_VM); - mutex_init(&constty_lock, MUTEX_DEFAULT, IPL_NONE); - constty_psz = pserialize_create(); tty_sigsih = softint_establish(SOFTINT_CLOCK, ttysigintr, NULL); KASSERT(tty_sigsih != NULL); Index: src/sys/sys/tty.h diff -u src/sys/sys/tty.h:1.100 src/sys/sys/tty.h:1.101 --- src/sys/sys/tty.h:1.100 Thu Oct 6 19:58:41 2022 +++ src/sys/sys/tty.h Fri Oct 7 18:59:37 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.100 2022/10/06 19:58:41 riastradh Exp $ */ +/* $NetBSD: tty.h,v 1.101 2022/10/07 18:59:37 riastradh Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -149,7 +149,6 @@ struct tty { int t_sigcount; /* # pending signals */ TAILQ_ENTRY(tty) t_sigqueue; /* entry on pending signal list */ void *t_softc; /* pointer to driver's softc. */ - volatile unsigned t_refcnt; /* reference count for constty */ }; #ifdef TTY_ALLOW_PRIVATE @@ -253,8 +252,6 @@ TAILQ_HEAD(ttylist_head, tty); /* the t #ifdef _KERNEL extern kmutex_t tty_lock; -extern kmutex_t constty_lock; -extern struct tty *volatile constty; extern int tty_count; /* number of ttys in global ttylist */ extern struct ttychars ttydefaults; @@ -316,8 +313,6 @@ void tty_free(struct tty *); u_char *firstc(struct clist *, int *); bool ttypull(struct tty *); int tty_unit(dev_t); -void tty_acquire(struct tty *); -void tty_release(struct tty *); int clalloc(struct clist *, int, int); void clfree(struct clist *);