Module Name: src Committed By: jmcneill Date: Mon Oct 11 18:39:06 UTC 2021
Modified Files: src/sys/dev/ic: com.c Log Message: com: speed up close with HUPCL set Instead of incurring a 1s penalty on close of a com device with HUPCL set, defer the sleep until the next open, and only sleep if necessary. This has a side effect of making `ttyflags -a` with a default install not pause for 1s for every non-console com device, which happens every boot via /etc/rc.d/ttys. To generate a diff of this commit: cvs rdiff -u -r1.365 -r1.366 src/sys/dev/ic/com.c 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/ic/com.c diff -u src/sys/dev/ic/com.c:1.365 src/sys/dev/ic/com.c:1.366 --- src/sys/dev/ic/com.c:1.365 Sat Jul 31 10:04:12 2021 +++ src/sys/dev/ic/com.c Mon Oct 11 18:39:06 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: com.c,v 1.365 2021/07/31 10:04:12 tnn Exp $ */ +/* $NetBSD: com.c,v 1.366 2021/10/11 18:39:06 jmcneill Exp $ */ /*- * Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.365 2021/07/31 10:04:12 tnn Exp $"); +__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.366 2021/10/11 18:39:06 jmcneill Exp $"); #include "opt_com.h" #include "opt_ddb.h" @@ -891,10 +891,8 @@ com_shutdown(struct com_softc *sc) */ if (ISSET(tp->t_cflag, HUPCL)) { com_modem(sc, 0); - mutex_spin_exit(&sc->sc_lock); - /* XXX will only timeout */ - (void) kpause(ttclos, false, hz, NULL); - mutex_spin_enter(&sc->sc_lock); + getmicrotime(&sc->sc_hup_pending); + sc->sc_hup_pending.tv_sec++; } /* Turn off interrupts. */ @@ -967,6 +965,7 @@ comopen(dev_t dev, int flag, int mode, s */ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; + struct timeval now, diff; tp->t_dev = dev; @@ -984,6 +983,18 @@ comopen(dev_t dev, int flag, int mode, s mutex_spin_enter(&sc->sc_lock); } + if (timerisset(&sc->sc_hup_pending)) { + getmicrotime(&now); + while (timercmp(&now, &sc->sc_hup_pending, <)) { + timersub(&sc->sc_hup_pending, &now, &diff); + int ms = now.tv_sec * 1000 + + uimin(now.tv_usec / 1000, 1); + kpause("comopen", false, mstohz(ms), + &sc->sc_lock); + } + timerclear(&sc->sc_hup_pending); + } + /* Turn on interrupts. */ sc->sc_ier = IER_ERXRDY | IER_ERLS; if (!ISSET(tp->t_cflag, CLOCAL))