[PATCH 3/4] tty: Lock tty pair in tty_init_dev()
From: Dmitry Safonov
Date: Tue Aug 28 2018 - 22:24:13 EST
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 <gregkh@xxxxxxxxxxxxxxxxxxx>
Cc: Jiri Slaby <jslaby@xxxxxxxx>
Signed-off-by: Dmitry Safonov <dima@xxxxxxxxxx>
---
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