summaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_ioctl.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 00:53:29 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 08:29:40 -0700
commit04f378b198da233ca0aca341b113dc6579d46123 (patch)
tree696e7bd401125cee71ecaa2047c4273f38732554 /drivers/char/tty_ioctl.c
parente52384426064bca0669a954736206adca7595d48 (diff)
downloadlinux-04f378b198da233ca0aca341b113dc6579d46123.tar.gz
linux-04f378b198da233ca0aca341b113dc6579d46123.tar.bz2
linux-04f378b198da233ca0aca341b113dc6579d46123.zip
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)
int canon_change;
struct ktermios old_termios = *tty->termios;
struct tty_ldisc *ld;
+ unsigned long flags;
/*
* Perform the actual termios internal changes under lock.
@@ -429,11 +430,13 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
STOP_CHAR(tty) == '\023' &&
START_CHAR(tty) == '\021');
if (old_flow != new_flow) {
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
if (new_flow)
tty->ctrl_status |= TIOCPKT_DOSTOP;
else
tty->ctrl_status |= TIOCPKT_NOSTOP;
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
wake_up_interruptible(&tty->link->read_wait);
}
}
@@ -905,6 +908,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct tty_struct *real_tty;
+ unsigned long flags;
int retval;
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -963,6 +967,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
return -ENOTTY;
if (get_user(pktmode, (int __user *) arg))
return -EFAULT;
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
if (pktmode) {
if (!tty->packet) {
tty->packet = 1;
@@ -970,6 +975,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
}
} else
tty->packet = 0;
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
return 0;
}
default: