Source-Changes-HG archive

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

[src/trunk]: src/sys tty(9): New ttycancel function.



details:   https://anonhg.NetBSD.org/src/rev/758335511a54
branches:  trunk
changeset: 364528:758335511a54
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Mar 28 12:39:28 2022 +0000

description:
tty(9): New ttycancel function.

This causes any current and future ttyopens to fail until ttyclose.

This is necessary for revoke to work reliably for device detach like
ucom(4) removable USB devices.  A tty driver for a removable device
needs some way to interrupt a pending .d_open so it returns promptly.
But ttyclose only interrupts ttyopen if it's already sleeping; it
won't cause a concurrent .d_open call which _will call_ but _hasn't
yet called_ ttyopen to avoid sleeping.  Using ttycancel in the tty
driver's .d_cancel makes this work.

diffstat:

 sys/kern/tty.c |  23 ++++++++++++++++++++---
 sys/sys/tty.h  |   5 ++++-
 2 files changed, 24 insertions(+), 4 deletions(-)

diffs (77 lines):

diff -r 995166ddd27e -r 758335511a54 sys/kern/tty.c
--- a/sys/kern/tty.c    Mon Mar 28 12:39:18 2022 +0000
+++ b/sys/kern/tty.c    Mon Mar 28 12:39:28 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tty.c,v 1.299 2021/12/05 07:44:53 msaitoh Exp $        */
+/*     $NetBSD: tty.c,v 1.300 2022/03/28 12:39:28 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.299 2021/12/05 07:44:53 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.300 2022/03/28 12:39:28 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -420,6 +420,21 @@
 }
 
 /*
+ * Interrupt any pending I/O and make it fail.  Used before close to
+ * interrupt pending open/read/write/&c. and make it fail promptly.
+ */
+void
+ttycancel(struct tty *tp)
+{
+
+       mutex_spin_enter(&tty_lock);
+       tp->t_state |= TS_CANCEL;
+       cv_broadcast(&tp->t_outcv);
+       cv_broadcast(&tp->t_rawcv);
+       mutex_spin_exit(&tty_lock);
+}
+
+/*
  * Handle close() on a tty line: flush and set to initial state,
  * bumping generation number so that pending read/write calls
  * can detect recycling of the tty.
@@ -2750,7 +2765,9 @@
        KASSERT(mutex_owned(&tty_lock));
 
        gen = tp->t_gen;
-       if (cv == NULL)
+       if (ISSET(tp->t_state, TS_CANCEL))
+               error = ERESTART;
+       else if (cv == NULL)
                error = kpause("ttypause", catch_p, timo, &tty_lock);
        else if (catch_p)
                error = cv_timedwait_sig(cv, &tty_lock, timo);
diff -r 995166ddd27e -r 758335511a54 sys/sys/tty.h
--- a/sys/sys/tty.h     Mon Mar 28 12:39:18 2022 +0000
+++ b/sys/sys/tty.h     Mon Mar 28 12:39:28 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tty.h,v 1.95 2019/01/27 02:08:50 pgoyette Exp $        */
+/*     $NetBSD: tty.h,v 1.96 2022/03/28 12:39:28 riastradh Exp $       */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -207,6 +207,8 @@
 #define        TS_KERN_ONLY    0x10000         /* Device is accessible by kernel
                                         * only, deny all userland access */
 
+#define        TS_CANCEL       0x20000         /* I/O cancelled pending close. */
+
 /* Character type information. */
 #define        ORDINARY        0
 #define        CONTROL         1
@@ -281,6 +283,7 @@
 int     ttwrite(struct tty *, struct uio *, int);
 void    ttychars(struct tty *);
 int     ttycheckoutq(struct tty *, int);
+void    ttycancel(struct tty *);
 int     ttyclose(struct tty *);
 void    ttyflush(struct tty *, int);
 void    ttygetinfo(struct tty *, int, char *, size_t);



Home | Main Index | Thread Index | Old Index