Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 364257
b: refs/heads/master
c: f4cf7a3
h: refs/heads/master
i:
  364255: 86fe476
v: v3
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Mar 18, 2013
1 parent 8603284 commit 759c25c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cf5284765862ac65e4a3e5b34652e593ffda2bdf
refs/heads/master: f4cf7a384587c16c59565dd6930dd763f243dba4
38 changes: 25 additions & 13 deletions trunk/drivers/tty/tty_ldisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,14 +530,17 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
/**
* tty_ldisc_halt - shut down the line discipline
* @tty: tty device
* @o_tty: paired pty device (can be NULL)
* @pending: returns true if work was scheduled when cancelled
* (can be set to NULL)
* @o_pending: returns true if work was scheduled when cancelled
* (can be set to NULL)
* @timeout: # of jiffies to wait for ldisc refs to be released
*
* Shut down the line discipline and work queue for this tty device.
* The TTY_LDISC flag being cleared ensures no further references can
* be obtained while the delayed work queue halt ensures that no more
* data is fed to the ldisc.
* Shut down the line discipline and work queue for this tty device and
* its paired pty (if exists). Clearing the TTY_LDISC flag ensures
* no further references can be obtained while the work queue halt
* ensures that no more data is fed to the ldisc.
*
* Furthermore, guarantee that existing ldisc references have been
* released, which in turn, guarantees that no future buffer work
Expand All @@ -548,19 +551,32 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
* flushed.
*/

static int tty_ldisc_halt(struct tty_struct *tty, int *pending, long timeout)
static int tty_ldisc_halt(struct tty_struct *tty, struct tty_struct *o_tty,
int *pending, int *o_pending, long timeout)
{
int scheduled, retval;
int scheduled, o_scheduled, retval;

clear_bit(TTY_LDISC, &tty->flags);
if (o_tty)
clear_bit(TTY_LDISC, &o_tty->flags);

retval = tty_ldisc_wait_idle(tty, timeout);
if (!retval && o_tty)
retval = tty_ldisc_wait_idle(o_tty, timeout);
if (retval)
return retval;

scheduled = cancel_work_sync(&tty->port->buf.work);
set_bit(TTY_LDISC_HALTED, &tty->flags);
if (o_tty) {
o_scheduled = cancel_work_sync(&o_tty->port->buf.work);
set_bit(TTY_LDISC_HALTED, &o_tty->flags);
}

if (pending)
*pending = scheduled;
if (o_tty && o_pending)
*o_pending = o_scheduled;
return 0;
}

Expand Down Expand Up @@ -702,9 +718,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
* parallel to the change and re-referencing the tty.
*/

retval = tty_ldisc_halt(tty, &work, 5 * HZ);
if (!retval && o_tty)
retval = tty_ldisc_halt(o_tty, &o_work, 5 * HZ);
retval = tty_ldisc_halt(tty, o_tty, &work, &o_work, 5 * HZ);

/*
* Wait for ->hangup_work and ->buf.work handlers to terminate.
Expand Down Expand Up @@ -965,12 +979,10 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
* race with the set_ldisc code path.
*/

tty_ldisc_halt(tty, NULL, MAX_SCHEDULE_TIMEOUT);
tty_ldisc_halt(tty, o_tty, NULL, NULL, MAX_SCHEDULE_TIMEOUT);
tty_ldisc_flush_works(tty);
if (o_tty) {
tty_ldisc_halt(o_tty, NULL, MAX_SCHEDULE_TIMEOUT);
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 */
Expand Down

0 comments on commit 759c25c

Please sign in to comment.