diff options
-rw-r--r-- | drivers/tty/pty.c | 10 | ||||
-rw-r--r-- | drivers/tty/tty_buffer.c | 6 | ||||
-rw-r--r-- | include/linux/tty.h | 4 |
3 files changed, 19 insertions, 1 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index f882ac81b93a..0e273158edac 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -212,10 +212,16 @@ static int pty_signal(struct tty_struct *tty, int sig) | |||
212 | static void pty_flush_buffer(struct tty_struct *tty) | 212 | static void pty_flush_buffer(struct tty_struct *tty) |
213 | { | 213 | { |
214 | struct tty_struct *to = tty->link; | 214 | struct tty_struct *to = tty->link; |
215 | struct tty_ldisc *ld; | ||
215 | 216 | ||
216 | if (!to) | 217 | if (!to) |
217 | return; | 218 | return; |
218 | /* tty_buffer_flush(to); FIXME */ | 219 | |
220 | ld = tty_ldisc_ref(to); | ||
221 | tty_buffer_flush(to, ld); | ||
222 | if (ld) | ||
223 | tty_ldisc_deref(ld); | ||
224 | |||
219 | if (to->packet) { | 225 | if (to->packet) { |
220 | spin_lock_irq(&tty->ctrl_lock); | 226 | spin_lock_irq(&tty->ctrl_lock); |
221 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; | 227 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; |
@@ -425,6 +431,8 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | |||
425 | tty->port = ports[1]; | 431 | tty->port = ports[1]; |
426 | o_tty->port->itty = o_tty; | 432 | o_tty->port->itty = o_tty; |
427 | 433 | ||
434 | tty_buffer_set_lock_subclass(o_tty->port); | ||
435 | |||
428 | tty_driver_kref_get(driver); | 436 | tty_driver_kref_get(driver); |
429 | tty->count++; | 437 | tty->count++; |
430 | o_tty->count++; | 438 | o_tty->count++; |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 3605103fc1ac..75661641f5fe 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -557,3 +557,9 @@ int tty_buffer_set_limit(struct tty_port *port, int limit) | |||
557 | return 0; | 557 | return 0; |
558 | } | 558 | } |
559 | EXPORT_SYMBOL_GPL(tty_buffer_set_limit); | 559 | EXPORT_SYMBOL_GPL(tty_buffer_set_limit); |
560 | |||
561 | /* slave ptys can claim nested buffer lock when handling BRK and INTR */ | ||
562 | void tty_buffer_set_lock_subclass(struct tty_port *port) | ||
563 | { | ||
564 | lockdep_set_subclass(&port->buf.lock, TTY_LOCK_SLAVE); | ||
565 | } | ||
diff --git a/include/linux/tty.h b/include/linux/tty.h index 849659908f23..55964b9490dd 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -25,6 +25,9 @@ | |||
25 | * | 25 | * |
26 | * legacy_mutex - Nested tty locks are necessary for releasing pty pairs. | 26 | * legacy_mutex - Nested tty locks are necessary for releasing pty pairs. |
27 | * The stable lock order is master pty first, then slave pty. | 27 | * The stable lock order is master pty first, then slave pty. |
28 | * tty_buffer lock - slave ptys can claim nested buffer lock when handling | ||
29 | * signal chars. The stable lock order is slave pty, then | ||
30 | * master. | ||
28 | */ | 31 | */ |
29 | 32 | ||
30 | enum { | 33 | enum { |
@@ -460,6 +463,7 @@ extern void tty_flush_to_ldisc(struct tty_struct *tty); | |||
460 | extern void tty_buffer_free_all(struct tty_port *port); | 463 | extern void tty_buffer_free_all(struct tty_port *port); |
461 | extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld); | 464 | extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld); |
462 | extern void tty_buffer_init(struct tty_port *port); | 465 | extern void tty_buffer_init(struct tty_port *port); |
466 | extern void tty_buffer_set_lock_subclass(struct tty_port *port); | ||
463 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); | 467 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); |
464 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); | 468 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); |
465 | extern void tty_termios_encode_baud_rate(struct ktermios *termios, | 469 | extern void tty_termios_encode_baud_rate(struct ktermios *termios, |