Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic com: speed up close with HUPCL set



details:   https://anonhg.NetBSD.org/src/rev/353b50de7e22
branches:  trunk
changeset: 989099:353b50de7e22
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Oct 11 18:39:06 2021 +0000

description:
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.

diffstat:

 sys/dev/ic/com.c |  23 +++++++++++++++++------
 1 files changed, 17 insertions(+), 6 deletions(-)

diffs (58 lines):

diff -r fbbbac1cf99b -r 353b50de7e22 sys/dev/ic/com.c
--- a/sys/dev/ic/com.c  Mon Oct 11 18:19:27 2021 +0000
+++ b/sys/dev/ic/com.c  Mon Oct 11 18:39:06 2021 +0000
@@ -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 @@
         */
        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 @@
         */
        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 @@
                        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))



Home | Main Index | Thread Index | Old Index