[PATCH -next 20/27] tty: Refactor __tty_hangup to enable lockdep annotation

Peter Hurley
2014-10-16T21:02:46Z

Refactor __tty_hangup() into:
1. __tty_hangup_common(), the portion requiring the tty lock
2. __tty_hangup(), which performs the pre- and post-lock processing
(TIOCCONS redirect undo) and calls through a function ptr parameter
to lock/hangup/unlock
3. __tty_hangup_standard(), which performs the lock/hangup/unlock

Allows an alternate function to lock/hangup/unlock with the
nested tty lock.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
drivers/tty/tty_io.c | 51 ++++++++++++++++++++++++++++++---------------------
1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 58015b3..48c1def 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -665,32 +665,17 @@ static int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
* tasklist_lock to walk task list for hangup event
* ->siglock to protect ->signal/->sighand
*/
-static void __tty_hangup(struct tty_struct *tty, int exit_session)
+static void __tty_hangup_common(struct tty_struct *tty, int exit_session)
{
struct file *cons_filp = NULL;
- struct file *filp, *f = NULL;
+ struct file *filp;
struct tty_file_private *priv;
int closecount = 0, n;
int refs;

- if (!tty)
+ if (test_bit(TTY_HUPPED, &tty->flags))
return;

-
- spin_lock(&redirect_lock);
- if (redirect && file_tty(redirect) == tty) {
- f = redirect;
- redirect = NULL;
- }
- spin_unlock(&redirect_lock);
-
- tty_lock(tty);
-
- if (test_bit(TTY_HUPPED, &tty->flags)) {
- tty_unlock(tty);
- return;
- }
-
/* inuse_filps is protected by the single tty lock,
this really needs to change if we want to flush the
workqueue with the lock held */
@@ -746,7 +731,31 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
* can't yet guarantee all that.
*/
set_bit(TTY_HUPPED, &tty->flags);
+}
+
+static void __tty_hangup_standard(struct tty_struct* tty, int exit_session)
+{
+ tty_lock(tty);
+ __tty_hangup_common(tty, exit_session);
tty_unlock(tty);
+}
+
+static void __tty_hangup(struct tty_struct *tty, int exit_session,
+ void (*hangup)(struct tty_struct *, int))
+{
+ struct file *f = NULL;
+
+ if (!tty)
+ return;
+
+ spin_lock(&redirect_lock);
+ if (redirect && file_tty(redirect) == tty) {
+ f = redirect;
+ redirect = NULL;
+ }
+ spin_unlock(&redirect_lock);
+
+ hangup(tty, exit_session);

if (f)
fput(f);
@@ -757,7 +766,7 @@ static void do_tty_hangup(struct work_struct *work)
struct tty_struct *tty =
container_of(work, struct tty_struct, hangup_work);

- __tty_hangup(tty, 0);
+ __tty_hangup(tty, 0, __tty_hangup_standard);
}

/**
@@ -795,7 +804,7 @@ void tty_vhangup(struct tty_struct *tty)

printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
#endif
- __tty_hangup(tty, 0);
+ __tty_hangup(tty, 0, __tty_hangup_standard);
}

EXPORT_SYMBOL(tty_vhangup);
@@ -836,7 +845,7 @@ static void tty_vhangup_session(struct tty_struct *tty)

printk(KERN_DEBUG "%s vhangup session...\n", tty_name(tty, buf));
#endif
- __tty_hangup(tty, 1);
+ __tty_hangup(tty, 1, __tty_hangup_standard);
}

/**
--
2.1.1