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))