diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2008-04-30 03:53:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:40 -0400 |
commit | 04f378b198da233ca0aca341b113dc6579d46123 (patch) | |
tree | 696e7bd401125cee71ecaa2047c4273f38732554 /drivers/char/n_hdlc.c | |
parent | e52384426064bca0669a954736206adca7595d48 (diff) |
tty: BKL pushdown
- Push the BKL down into the line disciplines
- Switch the tty layer to unlocked_ioctl
- Introduce a new ctrl_lock spin lock for the control bits
- Eliminate much of the lock_kernel use in n_tty
- Prepare to (but don't yet) call the drivers with the lock dropped
on the paths that historically held the lock
BKL now primarily protects open/close/ldisc change in the tty layer
[jirislaby@gmail.com: a couple of fixes]
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/n_hdlc.c')
-rw-r--r-- | drivers/char/n_hdlc.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index 06803ed5568c..a07c0af4819e 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -578,26 +578,36 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
578 | return -EFAULT; | 578 | return -EFAULT; |
579 | } | 579 | } |
580 | 580 | ||
581 | lock_kernel(); | ||
582 | |||
581 | for (;;) { | 583 | for (;;) { |
582 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | 584 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { |
585 | unlock_kernel(); | ||
583 | return -EIO; | 586 | return -EIO; |
587 | } | ||
584 | 588 | ||
585 | n_hdlc = tty2n_hdlc (tty); | 589 | n_hdlc = tty2n_hdlc (tty); |
586 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || | 590 | if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || |
587 | tty != n_hdlc->tty) | 591 | tty != n_hdlc->tty) { |
592 | unlock_kernel(); | ||
588 | return 0; | 593 | return 0; |
594 | } | ||
589 | 595 | ||
590 | rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); | 596 | rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); |
591 | if (rbuf) | 597 | if (rbuf) |
592 | break; | 598 | break; |
593 | 599 | ||
594 | /* no data */ | 600 | /* no data */ |
595 | if (file->f_flags & O_NONBLOCK) | 601 | if (file->f_flags & O_NONBLOCK) { |
602 | unlock_kernel(); | ||
596 | return -EAGAIN; | 603 | return -EAGAIN; |
604 | } | ||
597 | 605 | ||
598 | interruptible_sleep_on (&tty->read_wait); | 606 | interruptible_sleep_on (&tty->read_wait); |
599 | if (signal_pending(current)) | 607 | if (signal_pending(current)) { |
608 | unlock_kernel(); | ||
600 | return -EINTR; | 609 | return -EINTR; |
610 | } | ||
601 | } | 611 | } |
602 | 612 | ||
603 | if (rbuf->count > nr) | 613 | if (rbuf->count > nr) |
@@ -618,7 +628,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
618 | kfree(rbuf); | 628 | kfree(rbuf); |
619 | else | 629 | else |
620 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); | 630 | n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); |
621 | 631 | unlock_kernel(); | |
622 | return ret; | 632 | return ret; |
623 | 633 | ||
624 | } /* end of n_hdlc_tty_read() */ | 634 | } /* end of n_hdlc_tty_read() */ |
@@ -661,6 +671,8 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
661 | count = maxframe; | 671 | count = maxframe; |
662 | } | 672 | } |
663 | 673 | ||
674 | lock_kernel(); | ||
675 | |||
664 | add_wait_queue(&tty->write_wait, &wait); | 676 | add_wait_queue(&tty->write_wait, &wait); |
665 | set_current_state(TASK_INTERRUPTIBLE); | 677 | set_current_state(TASK_INTERRUPTIBLE); |
666 | 678 | ||
@@ -695,7 +707,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, | |||
695 | n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); | 707 | n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); |
696 | n_hdlc_send_frames(n_hdlc,tty); | 708 | n_hdlc_send_frames(n_hdlc,tty); |
697 | } | 709 | } |
698 | 710 | unlock_kernel(); | |
699 | return error; | 711 | return error; |
700 | 712 | ||
701 | } /* end of n_hdlc_tty_write() */ | 713 | } /* end of n_hdlc_tty_write() */ |