From cb5e9109eb58fa52efd3ed2f8e3c2e34aa1603e8 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 11 Mar 2013 16:44:35 -0400 Subject: [PATCH] --- yaml --- r: 364263 b: refs/heads/master c: a2965b7bee00a01731ae79de34c26e146cbd08cf h: refs/heads/master i: 364261: cf6ec64fa2444632f1f818210e4c0888079ffd2c 364259: 09a3a64a19f08f5b5f552dcfceab617583803bb7 364255: 86fe476a520aefc94cd988846f2a4dd92c539298 v: v3 --- [refs] | 2 +- trunk/drivers/tty/tty_io.c | 17 +++++++++++++++++ trunk/drivers/tty/tty_ldisc.c | 24 ++++-------------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/[refs] b/[refs] index f1c0e6e47e3f..109a5a55dfb9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4f98d4675166fc1991dbad7dd2af634df7c14061 +refs/heads/master: a2965b7bee00a01731ae79de34c26e146cbd08cf diff --git a/trunk/drivers/tty/tty_io.c b/trunk/drivers/tty/tty_io.c index 458763418701..95e97128e2ee 100644 --- a/trunk/drivers/tty/tty_io.c +++ b/trunk/drivers/tty/tty_io.c @@ -1510,6 +1510,17 @@ void tty_free_termios(struct tty_struct *tty) } EXPORT_SYMBOL(tty_free_termios); +/** + * tty_flush_works - flush all works of a tty + * @tty: tty device to flush works for + * + * Sync flush all works belonging to @tty. + */ +static void tty_flush_works(struct tty_struct *tty) +{ + flush_work(&tty->SAK_work); + flush_work(&tty->hangup_work); +} /** * release_one_tty - release tty structure memory @@ -1831,6 +1842,12 @@ int tty_release(struct inode *inode, struct file *filp) * Ask the line discipline code to release its structures */ tty_ldisc_release(tty, o_tty); + + /* Wait for pending work before tty destruction commmences */ + tty_flush_works(tty); + if (o_tty) + tty_flush_works(o_tty); + /* * The release_tty function takes care of the details of clearing * the slots and preserving the termios structure. The tty_unlock_pair diff --git a/trunk/drivers/tty/tty_ldisc.c b/trunk/drivers/tty/tty_ldisc.c index cbb945b03cdb..7f7e1a3d3825 100644 --- a/trunk/drivers/tty/tty_ldisc.c +++ b/trunk/drivers/tty/tty_ldisc.c @@ -498,18 +498,6 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) } } -/** - * tty_ldisc_flush_works - flush all works of a tty - * @tty: tty device to flush works for - * - * Sync flush all works belonging to @tty. - */ -static void tty_ldisc_flush_works(struct tty_struct *tty) -{ - flush_work(&tty->SAK_work); - flush_work(&tty->hangup_work); -} - /** * tty_ldisc_wait_idle - wait for the ldisc to become idle * @tty: tty to wait for @@ -698,13 +686,13 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) retval = tty_ldisc_halt(tty, o_tty, 5 * HZ); /* - * Wait for ->hangup_work and ->buf.work handlers to terminate. + * Wait for hangup to complete, if pending. * We must drop the mutex here in case a hangup is also in process. */ mutex_unlock(&tty->ldisc_mutex); - tty_ldisc_flush_works(tty); + flush_work(&tty->hangup_work); tty_lock(tty); mutex_lock(&tty->ldisc_mutex); @@ -951,15 +939,11 @@ static void tty_ldisc_kill(struct tty_struct *tty) void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) { /* - * Prevent flush_to_ldisc() from rescheduling the work for later. Then - * kill any delayed work. As this is the final close it does not - * race with the set_ldisc code path. + * Shutdown this line discipline. As this is the final close, + * it does not race with the set_ldisc code path. */ tty_ldisc_halt(tty, o_tty, MAX_SCHEDULE_TIMEOUT); - tty_ldisc_flush_works(tty); - if (o_tty) - tty_ldisc_flush_works(o_tty); tty_lock_pair(tty, o_tty); /* This will need doing differently if we need to lock */