mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
tty: Remove tty_wait_until_sent_from_close()
tty_wait_until_sent_from_close() drops the tty lock while waiting for the tty driver to finish sending previously accepted data (ie., data remaining in its write buffer and transmit fifo). tty_wait_until_sent_from_close() was added by commita57a7bf3fc("TTY: define tty_wait_until_sent_from_close") to prevent the entire tty subsystem from being unable to open new ttys while waiting for one tty to close while output drained. However, since commit0911261d4c("tty: Don't take tty_mutex for tty count changes"), holding a tty lock while closing does not prevent other ttys from being opened/closed/hung up, but only prevents lifetime event changes for the tty under lock. Holding the tty lock while waiting for output to drain does prevent parallel non-blocking opens (O_NONBLOCK) from advancing or returning while the tty lock is held. However, all parallel opens _already_ block even if the tty lock is dropped while closing and the parallel open advances. Blocking in open has been in mainline since at least 2.6.29 (see tty_port_block_til_ready(); note the test for O_NONBLOCK is _after_ the wait while ASYNC_CLOSING). IOW, before this patch a non-blocking open will sleep anyway for the _entire_ duration of a parallel hardware shutdown, and when it wakes, the error return will cause a release of its tty, and it will restart with a fresh attempt to open. Similarly with a blocking open that is already waiting; when it's woken, the hardware shutdown has already completed to ASYNC_INITIALIZED is not set, which forces a release and restart as well. So, holding the tty lock across the _entire_ close (which is what this patch does), even while waiting for output to drain, is equivalent to the current outcome wrt parallel opens. Cc: Alan Cox <[email protected]> Cc: David Laight <[email protected]> CC: Arnd Bergmann <[email protected]> CC: Karsten Keil <[email protected]> CC: [email protected] Signed-off-by: Peter Hurley <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
parent
32ede4a517
commit
79c1faa451
5 changed files with 5 additions and 30 deletions
|
|
@ -418,7 +418,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
|
|||
* there is no buffered data otherwise sleeps on a wait queue
|
||||
* waking periodically to check chars_in_buffer().
|
||||
*/
|
||||
tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT);
|
||||
tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
|
||||
} else {
|
||||
if (hp->port.count < 0)
|
||||
printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
|
||||
|
|
|
|||
|
|
@ -1230,7 +1230,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
|
|||
irq = hvcsd->vdev->irq;
|
||||
spin_unlock_irqrestore(&hvcsd->lock, flags);
|
||||
|
||||
tty_wait_until_sent_from_close(tty, HVCS_CLOSE_WAIT);
|
||||
tty_wait_until_sent(tty, HVCS_CLOSE_WAIT);
|
||||
|
||||
/*
|
||||
* This line is important because it tells hvcs_open that this
|
||||
|
|
|
|||
|
|
@ -463,10 +463,7 @@ static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty)
|
|||
schedule_timeout_interruptible(timeout);
|
||||
}
|
||||
|
||||
/* Caller holds tty lock.
|
||||
* NB: may drop and reacquire tty lock (in tty_wait_until_sent_from_close())
|
||||
* so tty and tty port may have changed state (but not hung up or reopened).
|
||||
*/
|
||||
/* Caller holds tty lock. */
|
||||
int tty_port_close_start(struct tty_port *port,
|
||||
struct tty_struct *tty, struct file *filp)
|
||||
{
|
||||
|
|
@ -502,7 +499,7 @@ int tty_port_close_start(struct tty_port *port,
|
|||
if (tty->flow_stopped)
|
||||
tty_driver_flush_buffer(tty);
|
||||
if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
|
||||
tty_wait_until_sent_from_close(tty, port->closing_wait);
|
||||
tty_wait_until_sent(tty, port->closing_wait);
|
||||
if (port->drain_delay)
|
||||
tty_port_drain_delay(port, tty);
|
||||
}
|
||||
|
|
@ -543,10 +540,6 @@ EXPORT_SYMBOL(tty_port_close_end);
|
|||
* tty_port_close
|
||||
*
|
||||
* Caller holds tty lock
|
||||
*
|
||||
* NB: may drop and reacquire tty lock (in tty_port_close_start()->
|
||||
* tty_wait_until_sent_from_close()) so tty and tty_port may have changed
|
||||
* state (but not hung up or reopened).
|
||||
*/
|
||||
void tty_port_close(struct tty_port *port, struct tty_struct *tty,
|
||||
struct file *filp)
|
||||
|
|
|
|||
Loading…
Reference in a new issue