pty: avoid forcing 'low_latency' tty flag
We really don't want to mark the pty as a low-latency device, because as Alan points out, the ->write method can be called from an IRQ (ppp?), and that means we can't use ->low_latency=1 as we take mutexes in the low_latency case. So rather than using low_latency to force the written data to be pushed to the ldisc handling at 'write()' time, just make the reader side (or the poll function) do the flush when it checks whether there is data to be had. This also fixes the problem with lost data in an emacs compile buffer (bugzilla 13815), and we can thus revert the low_latency pty hack (commit 3a54297478e6578f96fd54bf4daa1751130aca86: "pty: quickfix for the pty ENXIO timing problems"). Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> [ Modified to do the tty_flush_to_ldisc() inside input_available_p() so that it triggers for both read and poll() - Linus] Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
7d3e91b8a1
Коммит
e043e42bdb
|
@ -1583,6 +1583,7 @@ static int n_tty_open(struct tty_struct *tty)
|
|||
|
||||
static inline int input_available_p(struct tty_struct *tty, int amt)
|
||||
{
|
||||
tty_flush_to_ldisc(tty);
|
||||
if (tty->icanon) {
|
||||
if (tty->canon_data)
|
||||
return 1;
|
||||
|
|
|
@ -52,7 +52,6 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
|
|||
return;
|
||||
tty->link->packet = 0;
|
||||
set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
|
||||
tty_flip_buffer_push(tty->link);
|
||||
wake_up_interruptible(&tty->link->read_wait);
|
||||
wake_up_interruptible(&tty->link->write_wait);
|
||||
if (tty->driver->subtype == PTY_TYPE_MASTER) {
|
||||
|
@ -208,7 +207,6 @@ static int pty_open(struct tty_struct *tty, struct file *filp)
|
|||
clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
|
||||
set_bit(TTY_THROTTLED, &tty->flags);
|
||||
retval = 0;
|
||||
tty->low_latency = 1;
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -461,6 +461,19 @@ static void flush_to_ldisc(struct work_struct *work)
|
|||
tty_ldisc_deref(disc);
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_flush_to_ldisc
|
||||
* @tty: tty to push
|
||||
*
|
||||
* Push the terminal flip buffers to the line discipline.
|
||||
*
|
||||
* Must not be called from IRQ context.
|
||||
*/
|
||||
void tty_flush_to_ldisc(struct tty_struct *tty)
|
||||
{
|
||||
flush_to_ldisc(&tty->buf.work.work);
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_flip_buffer_push - terminal
|
||||
* @tty: tty to push
|
||||
|
|
|
@ -394,6 +394,7 @@ extern void __do_SAK(struct tty_struct *tty);
|
|||
extern void disassociate_ctty(int priv);
|
||||
extern void no_tty(void);
|
||||
extern void tty_flip_buffer_push(struct tty_struct *tty);
|
||||
extern void tty_flush_to_ldisc(struct tty_struct *tty);
|
||||
extern void tty_buffer_free_all(struct tty_struct *tty);
|
||||
extern void tty_buffer_flush(struct tty_struct *tty);
|
||||
extern void tty_buffer_init(struct tty_struct *tty);
|
||||
|
|
Загрузка…
Ссылка в новой задаче