aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_ioctl.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:53:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:40 -0400
commit04f378b198da233ca0aca341b113dc6579d46123 (patch)
tree696e7bd401125cee71ecaa2047c4273f38732554 /drivers/char/tty_ioctl.c
parente52384426064bca0669a954736206adca7595d48 (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/tty_ioctl.c')
-rw-r--r--drivers/char/tty_ioctl.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index f95a80b2265f..d6353d89b451 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -395,6 +395,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
395 int canon_change; 395 int canon_change;
396 struct ktermios old_termios = *tty->termios; 396 struct ktermios old_termios = *tty->termios;
397 struct tty_ldisc *ld; 397 struct tty_ldisc *ld;
398 unsigned long flags;
398 399
399 /* 400 /*
400 * Perform the actual termios internal changes under lock. 401 * Perform the actual termios internal changes under lock.
@@ -429,11 +430,13 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
429 STOP_CHAR(tty) == '\023' && 430 STOP_CHAR(tty) == '\023' &&
430 START_CHAR(tty) == '\021'); 431 START_CHAR(tty) == '\021');
431 if (old_flow != new_flow) { 432 if (old_flow != new_flow) {
433 spin_lock_irqsave(&tty->ctrl_lock, flags);
432 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); 434 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
433 if (new_flow) 435 if (new_flow)
434 tty->ctrl_status |= TIOCPKT_DOSTOP; 436 tty->ctrl_status |= TIOCPKT_DOSTOP;
435 else 437 else
436 tty->ctrl_status |= TIOCPKT_NOSTOP; 438 tty->ctrl_status |= TIOCPKT_NOSTOP;
439 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
437 wake_up_interruptible(&tty->link->read_wait); 440 wake_up_interruptible(&tty->link->read_wait);
438 } 441 }
439 } 442 }
@@ -905,6 +908,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
905 unsigned int cmd, unsigned long arg) 908 unsigned int cmd, unsigned long arg)
906{ 909{
907 struct tty_struct *real_tty; 910 struct tty_struct *real_tty;
911 unsigned long flags;
908 int retval; 912 int retval;
909 913
910 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 914 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -963,6 +967,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
963 return -ENOTTY; 967 return -ENOTTY;
964 if (get_user(pktmode, (int __user *) arg)) 968 if (get_user(pktmode, (int __user *) arg))
965 return -EFAULT; 969 return -EFAULT;
970 spin_lock_irqsave(&tty->ctrl_lock, flags);
966 if (pktmode) { 971 if (pktmode) {
967 if (!tty->packet) { 972 if (!tty->packet) {
968 tty->packet = 1; 973 tty->packet = 1;
@@ -970,6 +975,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
970 } 975 }
971 } else 976 } else
972 tty->packet = 0; 977 tty->packet = 0;
978 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
973 return 0; 979 return 0;
974 } 980 }
975 default: 981 default: