aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2009-07-29 15:15:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-07-29 15:15:56 -0400
commite043e42bdb66885b3ac10d27a01ccb9972e2b0a3 (patch)
tree12b40fd776f653484a77fd84f07cc304276141b1
parent7d3e91b8a1f5179d56a7412d4b499f2d5fc6b25d (diff)
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>
-rw-r--r--drivers/char/n_tty.c1
-rw-r--r--drivers/char/pty.c2
-rw-r--r--drivers/char/tty_buffer.c13
-rw-r--r--include/linux/tty.h1
4 files changed, 15 insertions, 2 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index ff47907ff1bf..973be2f44195 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1583,6 +1583,7 @@ static int n_tty_open(struct tty_struct *tty)
1583 1583
1584static inline int input_available_p(struct tty_struct *tty, int amt) 1584static inline int input_available_p(struct tty_struct *tty, int amt)
1585{ 1585{
1586 tty_flush_to_ldisc(tty);
1586 if (tty->icanon) { 1587 if (tty->icanon) {
1587 if (tty->canon_data) 1588 if (tty->canon_data)
1588 return 1; 1589 return 1;
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 3850a68f265a..6e6942c45f5b 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -52,7 +52,6 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
52 return; 52 return;
53 tty->link->packet = 0; 53 tty->link->packet = 0;
54 set_bit(TTY_OTHER_CLOSED, &tty->link->flags); 54 set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
55 tty_flip_buffer_push(tty->link);
56 wake_up_interruptible(&tty->link->read_wait); 55 wake_up_interruptible(&tty->link->read_wait);
57 wake_up_interruptible(&tty->link->write_wait); 56 wake_up_interruptible(&tty->link->write_wait);
58 if (tty->driver->subtype == PTY_TYPE_MASTER) { 57 if (tty->driver->subtype == PTY_TYPE_MASTER) {
@@ -208,7 +207,6 @@ static int pty_open(struct tty_struct *tty, struct file *filp)
208 clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); 207 clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
209 set_bit(TTY_THROTTLED, &tty->flags); 208 set_bit(TTY_THROTTLED, &tty->flags);
210 retval = 0; 209 retval = 0;
211 tty->low_latency = 1;
212out: 210out:
213 return retval; 211 return retval;
214} 212}
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index 810ee25d66a4..3108991c5c8b 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -462,6 +462,19 @@ static void flush_to_ldisc(struct work_struct *work)
462} 462}
463 463
464/** 464/**
465 * tty_flush_to_ldisc
466 * @tty: tty to push
467 *
468 * Push the terminal flip buffers to the line discipline.
469 *
470 * Must not be called from IRQ context.
471 */
472void tty_flush_to_ldisc(struct tty_struct *tty)
473{
474 flush_to_ldisc(&tty->buf.work.work);
475}
476
477/**
465 * tty_flip_buffer_push - terminal 478 * tty_flip_buffer_push - terminal
466 * @tty: tty to push 479 * @tty: tty to push
467 * 480 *
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 1488d8c81aac..e8c6c9136c97 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -394,6 +394,7 @@ extern void __do_SAK(struct tty_struct *tty);
394extern void disassociate_ctty(int priv); 394extern void disassociate_ctty(int priv);
395extern void no_tty(void); 395extern void no_tty(void);
396extern void tty_flip_buffer_push(struct tty_struct *tty); 396extern void tty_flip_buffer_push(struct tty_struct *tty);
397extern void tty_flush_to_ldisc(struct tty_struct *tty);
397extern void tty_buffer_free_all(struct tty_struct *tty); 398extern void tty_buffer_free_all(struct tty_struct *tty);
398extern void tty_buffer_flush(struct tty_struct *tty); 399extern void tty_buffer_flush(struct tty_struct *tty);
399extern void tty_buffer_init(struct tty_struct *tty); 400extern void tty_buffer_init(struct tty_struct *tty);