diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/tty/pty.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/tty/pty.c')
-rw-r--r-- | kernel/drivers/tty/pty.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/kernel/drivers/tty/pty.c b/kernel/drivers/tty/pty.c index 4d5e84097..78e983677 100644 --- a/kernel/drivers/tty/pty.c +++ b/kernel/drivers/tty/pty.c @@ -7,7 +7,6 @@ */ #include <linux/module.h> - #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/tty.h> @@ -26,6 +25,12 @@ #include <linux/mutex.h> #include <linux/poll.h> +#undef TTY_DEBUG_HANGUP +#ifdef TTY_DEBUG_HANGUP +# define tty_debug_hangup(tty, f, args...) tty_debug(tty, f, ##args) +#else +# define tty_debug_hangup(tty, f, args...) do {} while (0) +#endif #ifdef CONFIG_UNIX98_PTYS static struct tty_driver *ptm_driver; @@ -495,6 +500,10 @@ static int pty_bsd_ioctl(struct tty_struct *tty, } static int legacy_count = CONFIG_LEGACY_PTY_COUNT; +/* + * not really modular, but the easiest way to keep compat with existing + * bootargs behaviour is to continue using module_param here. + */ module_param(legacy_count, int, 0); /* @@ -672,7 +681,14 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) /* this is called once with whichever end is closed last */ static void pty_unix98_shutdown(struct tty_struct *tty) { - devpts_kill_index(tty->driver_data, tty->index); + struct inode *ptmx_inode; + + if (tty->driver->subtype == PTY_TYPE_MASTER) + ptmx_inode = tty->driver_data; + else + ptmx_inode = tty->link->driver_data; + devpts_kill_index(ptmx_inode, tty->index); + devpts_del_ref(ptmx_inode); } static const struct tty_operations ptm_unix98_ops = { @@ -764,6 +780,18 @@ static int ptmx_open(struct inode *inode, struct file *filp) set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ tty->driver_data = inode; + /* + * In the case where all references to ptmx inode are dropped and we + * still have /dev/tty opened pointing to the master/slave pair (ptmx + * is closed/released before /dev/tty), we must make sure that the inode + * is still valid when we call the final pty_unix98_shutdown, thus we + * hold an additional reference to the ptmx inode. For the same /dev/tty + * last close case, we also need to make sure the super_block isn't + * destroyed (devpts instance unmounted), before /dev/tty is closed and + * on its release devpts_kill_index is called. + */ + devpts_add_ref(inode); + tty_add_file(tty, filp); slave_inode = devpts_pty_new(inode, @@ -779,6 +807,8 @@ static int ptmx_open(struct inode *inode, struct file *filp) if (retval) goto err_release; + tty_debug_hangup(tty, "(tty count=%d)\n", tty->count); + tty_unlock(tty); return 0; err_release: @@ -869,4 +899,4 @@ static int __init pty_init(void) unix98_pty_init(); return 0; } -module_init(pty_init); +device_initcall(pty_init); |