pty: avoid forcing 'low_latency' tty flag
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Wed, 29 Jul 2009 19:15:56 +0000 (12:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Jul 2009 19:15:56 +0000 (12:15 -0700)
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>
drivers/char/n_tty.c
drivers/char/pty.c
drivers/char/tty_buffer.c
include/linux/tty.h

index ff47907ff1bf9f9ae8ddc3e073c06ae4f3a615df..973be2f441951ed0e68d658c1192c94524f33aff 100644 (file)
@@ -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;
index 3850a68f265ae56ef8fd601d1ca36bf12b339f31..6e6942c45f5b6cb76d6c1aaf91ed96fee9185ae7 100644 (file)
@@ -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;
 }
index 810ee25d66a48fa5042c84b7f4cf47f0a870ef4e..3108991c5c8b60f312742ca4eaeb37e4c812ad4c 100644 (file)
@@ -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
index 1488d8c81aac6587c9edc8002f39f89d104391cf..e8c6c9136c97c4ab95fd6d39784b86e88baf80c8 100644 (file)
@@ -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);