It's safe to not lock both here - done to silence attempt lockdep assert in tty_ldisc_open(), which will be added with following patch.
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org> Cc: Jiri Slaby <jsl...@suse.com> Signed-off-by: Dmitry Safonov <d...@arista.com> --- drivers/tty/tty_io.c | 5 ++--- drivers/tty/tty_ldisc.c | 6 ++---- include/linux/tty.h | 4 ++++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3ef8b977b167..a94005f915b3 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1342,7 +1342,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", __func__, tty->driver->name); - retval = tty_ldisc_lock(tty, 5 * HZ); + retval = tty_ldisc_lock_pair_timeout(tty, tty->link, 5 * HZ); if (retval) goto err_release_lock; tty->port->itty = tty; @@ -1353,9 +1353,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) * to decrement the use counts, as release_tty doesn't care. */ retval = tty_ldisc_setup(tty, tty->link); + tty_ldisc_unlock_pair(tty, tty->link); if (retval) goto err_release_tty; - tty_ldisc_unlock(tty); /* Return the tty locked so that it cannot vanish under the caller */ return tty; @@ -1368,7 +1368,6 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) /* call the tty release_tty routine to clean out this slot */ err_release_tty: - tty_ldisc_unlock(tty); tty_info_ratelimited(tty, "ldisc open failed (%d), clearing slot %d\n", retval, idx); err_release_lock: diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index fc4c97cae01e..b72266461c00 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -340,8 +340,7 @@ void tty_ldisc_unlock(struct tty_struct *tty) __tty_ldisc_unlock(tty); } -static int -tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2, +int tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2, unsigned long timeout) { int ret; @@ -381,8 +380,7 @@ static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2) tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT); } -static void tty_ldisc_unlock_pair(struct tty_struct *tty, - struct tty_struct *tty2) +void tty_ldisc_unlock_pair(struct tty_struct *tty, struct tty_struct *tty2) { __tty_ldisc_unlock(tty); if (tty2) diff --git a/include/linux/tty.h b/include/linux/tty.h index c56e3978b00f..5efb8f87ffdc 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -409,6 +409,10 @@ extern void tty_kclose(struct tty_struct *tty); extern int tty_dev_name_to_number(const char *name, dev_t *number); extern int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout); extern void tty_ldisc_unlock(struct tty_struct *tty); +extern int tty_ldisc_lock_pair_timeout(struct tty_struct *tty, + struct tty_struct *tty2, unsigned long timeout); +extern void tty_ldisc_unlock_pair(struct tty_struct *tty, + struct tty_struct *tty2); #else static inline void tty_kref_put(struct tty_struct *tty) { } -- 2.13.6