aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-06-11 07:50:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 11:51:01 -0400
commitc65c9bc3efa5589f691276bb9db689119a711222 (patch)
treeccb86ffb28ecafa77623fb2789faae8e4c1e2c4b /drivers/char/tty_io.c
parente8b70e7d3e86319a8b2aaabde3866833d92cd80f (diff)
tty: rewrite the ldisc locking
There are several pretty much unfixable races in the old ldisc code, especially with respect to pty behaviour and also to hangup. It's easier to rewrite the code than simply try and patch it up. This patch - splits the ldisc from the tty (so we will be able to refcount it more cleanly later) - introduces a mutex lock for ldisc changing on an active device - fixes the complete mess that hangup caused - implements hopefully correct setldisc/close/hangup locking There are still some problems around pty pairs that have always been there but at least it is now possible to understand the code and fix further problems. This fixes the following known bugs - hang up can leak ldisc references - hang up may not call open/close on ldisc in a matched way - pty/tty pairs can deadlock during an ldisc change - reading the ldisc proc files can cause every ldisc to be loaded and probably a few other of the mysterious ldisc race reports. I'm sure it also adds the odd new one. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c64
1 files changed, 8 insertions, 56 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index be49d0730bb9..2f44b0b241c3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -492,22 +492,6 @@ void tty_ldisc_flush(struct tty_struct *tty)
492EXPORT_SYMBOL_GPL(tty_ldisc_flush); 492EXPORT_SYMBOL_GPL(tty_ldisc_flush);
493 493
494/** 494/**
495 * tty_reset_termios - reset terminal state
496 * @tty: tty to reset
497 *
498 * Restore a terminal to the driver default state
499 */
500
501static void tty_reset_termios(struct tty_struct *tty)
502{
503 mutex_lock(&tty->termios_mutex);
504 *tty->termios = tty->driver->init_termios;
505 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
506 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
507 mutex_unlock(&tty->termios_mutex);
508}
509
510/**
511 * do_tty_hangup - actual handler for hangup events 495 * do_tty_hangup - actual handler for hangup events
512 * @work: tty device 496 * @work: tty device
513 * 497 *
@@ -536,7 +520,6 @@ static void do_tty_hangup(struct work_struct *work)
536 struct file *cons_filp = NULL; 520 struct file *cons_filp = NULL;
537 struct file *filp, *f = NULL; 521 struct file *filp, *f = NULL;
538 struct task_struct *p; 522 struct task_struct *p;
539 struct tty_ldisc *ld;
540 int closecount = 0, n; 523 int closecount = 0, n;
541 unsigned long flags; 524 unsigned long flags;
542 int refs = 0; 525 int refs = 0;
@@ -567,40 +550,8 @@ static void do_tty_hangup(struct work_struct *work)
567 filp->f_op = &hung_up_tty_fops; 550 filp->f_op = &hung_up_tty_fops;
568 } 551 }
569 file_list_unlock(); 552 file_list_unlock();
570 /*
571 * FIXME! What are the locking issues here? This may me overdoing
572 * things... This question is especially important now that we've
573 * removed the irqlock.
574 */
575 ld = tty_ldisc_ref(tty);
576 if (ld != NULL) {
577 /* We may have no line discipline at this point */
578 if (ld->ops->flush_buffer)
579 ld->ops->flush_buffer(tty);
580 tty_driver_flush_buffer(tty);
581 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
582 ld->ops->write_wakeup)
583 ld->ops->write_wakeup(tty);
584 if (ld->ops->hangup)
585 ld->ops->hangup(tty);
586 }
587 /*
588 * FIXME: Once we trust the LDISC code better we can wait here for
589 * ldisc completion and fix the driver call race
590 */
591 wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
592 wake_up_interruptible_poll(&tty->read_wait, POLLIN);
593 /*
594 * Shutdown the current line discipline, and reset it to
595 * N_TTY.
596 */
597 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
598 tty_reset_termios(tty);
599 /* Defer ldisc switch */
600 /* tty_deferred_ldisc_switch(N_TTY);
601 553
602 This should get done automatically when the port closes and 554 tty_ldisc_hangup(tty);
603 tty_release is called */
604 555
605 read_lock(&tasklist_lock); 556 read_lock(&tasklist_lock);
606 if (tty->session) { 557 if (tty->session) {
@@ -629,12 +580,15 @@ static void do_tty_hangup(struct work_struct *work)
629 read_unlock(&tasklist_lock); 580 read_unlock(&tasklist_lock);
630 581
631 spin_lock_irqsave(&tty->ctrl_lock, flags); 582 spin_lock_irqsave(&tty->ctrl_lock, flags);
632 tty->flags = 0; 583 clear_bit(TTY_THROTTLED, &tty->flags);
584 clear_bit(TTY_PUSH, &tty->flags);
585 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
633 put_pid(tty->session); 586 put_pid(tty->session);
634 put_pid(tty->pgrp); 587 put_pid(tty->pgrp);
635 tty->session = NULL; 588 tty->session = NULL;
636 tty->pgrp = NULL; 589 tty->pgrp = NULL;
637 tty->ctrl_status = 0; 590 tty->ctrl_status = 0;
591 set_bit(TTY_HUPPED, &tty->flags);
638 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 592 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
639 593
640 /* Account for the p->signal references we killed */ 594 /* Account for the p->signal references we killed */
@@ -660,10 +614,7 @@ static void do_tty_hangup(struct work_struct *work)
660 * can't yet guarantee all that. 614 * can't yet guarantee all that.
661 */ 615 */
662 set_bit(TTY_HUPPED, &tty->flags); 616 set_bit(TTY_HUPPED, &tty->flags);
663 if (ld) { 617 tty_ldisc_enable(tty);
664 tty_ldisc_enable(tty);
665 tty_ldisc_deref(ld);
666 }
667 unlock_kernel(); 618 unlock_kernel();
668 if (f) 619 if (f)
669 fput(f); 620 fput(f);
@@ -2570,7 +2521,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2570 case TIOCGSID: 2521 case TIOCGSID:
2571 return tiocgsid(tty, real_tty, p); 2522 return tiocgsid(tty, real_tty, p);
2572 case TIOCGETD: 2523 case TIOCGETD:
2573 return put_user(tty->ldisc.ops->num, (int __user *)p); 2524 return put_user(tty->ldisc->ops->num, (int __user *)p);
2574 case TIOCSETD: 2525 case TIOCSETD:
2575 return tiocsetd(tty, p); 2526 return tiocsetd(tty, p);
2576 /* 2527 /*
@@ -2785,6 +2736,7 @@ void initialize_tty_struct(struct tty_struct *tty,
2785 tty->buf.head = tty->buf.tail = NULL; 2736 tty->buf.head = tty->buf.tail = NULL;
2786 tty_buffer_init(tty); 2737 tty_buffer_init(tty);
2787 mutex_init(&tty->termios_mutex); 2738 mutex_init(&tty->termios_mutex);
2739 mutex_init(&tty->ldisc_mutex);
2788 init_waitqueue_head(&tty->write_wait); 2740 init_waitqueue_head(&tty->write_wait);
2789 init_waitqueue_head(&tty->read_wait); 2741 init_waitqueue_head(&tty->read_wait);
2790 INIT_WORK(&tty->hangup_work, do_tty_hangup); 2742 INIT_WORK(&tty->hangup_work, do_tty_hangup);