aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/tty.h
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2016-01-10 22:41:06 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-01-27 15:01:44 -0800
commit892d1fa7eaaed9d3c04954cb140c34ebc3393932 (patch)
treec85eb2b4043f4dcac9a57f610dd1aee7c9be1070 /include/linux/tty.h
parenttty: Refactor tty_ldisc_reinit() for reuse (diff)
downloadlinux-dev-892d1fa7eaaed9d3c04954cb140c34ebc3393932.tar.xz
linux-dev-892d1fa7eaaed9d3c04954cb140c34ebc3393932.zip
tty: Destroy ldisc instance on hangup
Currently, when the tty is hungup, the ldisc is re-instanced; ie., the current instance is destroyed and a new instance is created. The purpose of this design was to guarantee a valid, open ldisc for the lifetime of the tty. However, now that tty buffers are owned by and have lifetime equivalent to the tty_port (since v3.10), any data received immediately after the ldisc is re-instanced may cause continued driver i/o operations concurrently with the driver's hangup() operation. For drivers that shutdown h/w on hangup, this is unexpected and usually bad. For example, the serial core may free the xmit buffer page concurrently with an in-progress write() operation (triggered by echo). With the existing stable and robust ldisc reference handling, the cleaned-up tty_reopen(), the straggling unsafe ldisc use cleaned up, and the preparation to properly handle a NULL tty->ldisc, the ldisc instance can be destroyed and only re-instanced when the tty is re-opened. If the tty was opened as /dev/console or /dev/tty0, the original behavior of re-instancing the ldisc is retained (the 'reinit' parameter to tty_ldisc_hangup() is true). This is required since those file descriptors are never hungup. This patch has neglible impact on userspace; the tty file_operations ptr is changed to point to the hungup file operations _before_ the ldisc instance is destroyed, so only racing file operations might now retrieve a NULL ldisc reference (which is simply handled as if the hungup file operation had been called instead -- see "tty: Prepare for destroying line discipline on hangup"). This resolves a long-standing FIXME and several crash reports. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/tty.h')
-rw-r--r--include/linux/tty.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/tty.h b/include/linux/tty.h
index e3b0afbde7b9..95e52c6b9696 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -490,7 +490,8 @@ extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt);
extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
extern void tty_ldisc_deref(struct tty_ldisc *);
extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *);
-extern void tty_ldisc_hangup(struct tty_struct *tty);
+extern void tty_ldisc_hangup(struct tty_struct *tty, bool reset);
+extern int tty_ldisc_reinit(struct tty_struct *tty, int disc);
extern const struct file_operations tty_ldiscs_proc_fops;
extern void tty_wakeup(struct tty_struct *tty);