aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-08-06 15:40:30 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 16:47:44 -0400
commitb07471fa51358ce64cc25e1501544502362e4404 (patch)
tree0bd1889eb3cbabe51f15cc5e971f9644cdced0f3
parentddcd9fb66ae7f448b517242c10a31d4e17bcad45 (diff)
tty: implement BTM as mutex instead of BKL
The tty locking now follows the rules for mutexes, so we can replace the BKL usage with a new subsystem wide mutex. Using a regular mutex here will change the behaviour when blocked on the BTM from spinning to sleeping, but that should not be visible to the user. Using the mutex also means that all the BTM is now covered by lockdep. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/tty_mutex.c47
-rw-r--r--include/linux/tty.h18
3 files changed, 53 insertions, 13 deletions
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 273cee1cc77b..dc9641660605 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -9,6 +9,7 @@ FONTMAPFILE = cp437.uni
9 9
10obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o 10obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o
11 11
12obj-y += tty_mutex.o
12obj-$(CONFIG_LEGACY_PTYS) += pty.o 13obj-$(CONFIG_LEGACY_PTYS) += pty.o
13obj-$(CONFIG_UNIX98_PTYS) += pty.o 14obj-$(CONFIG_UNIX98_PTYS) += pty.o
14obj-y += misc.o 15obj-y += misc.o
diff --git a/drivers/char/tty_mutex.c b/drivers/char/tty_mutex.c
new file mode 100644
index 000000000000..133697540c73
--- /dev/null
+++ b/drivers/char/tty_mutex.c
@@ -0,0 +1,47 @@
1/*
2 * drivers/char/tty_lock.c
3 */
4#include <linux/tty.h>
5#include <linux/module.h>
6#include <linux/kallsyms.h>
7#include <linux/semaphore.h>
8#include <linux/sched.h>
9
10/*
11 * The 'big tty mutex'
12 *
13 * This mutex is taken and released by tty_lock() and tty_unlock(),
14 * replacing the older big kernel lock.
15 * It can no longer be taken recursively, and does not get
16 * released implicitly while sleeping.
17 *
18 * Don't use in new code.
19 */
20static DEFINE_MUTEX(big_tty_mutex);
21struct task_struct *__big_tty_mutex_owner;
22EXPORT_SYMBOL_GPL(__big_tty_mutex_owner);
23
24/*
25 * Getting the big tty mutex.
26 */
27void __lockfunc tty_lock(void)
28{
29 struct task_struct *task = current;
30
31 WARN_ON(__big_tty_mutex_owner == task);
32
33 mutex_lock(&big_tty_mutex);
34 __big_tty_mutex_owner = task;
35}
36EXPORT_SYMBOL(tty_lock);
37
38void __lockfunc tty_unlock(void)
39{
40 struct task_struct *task = current;
41
42 WARN_ON(__big_tty_mutex_owner != task);
43 __big_tty_mutex_owner = NULL;
44
45 mutex_unlock(&big_tty_mutex);
46}
47EXPORT_SYMBOL(tty_unlock);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 0fbafb0b69bf..1437da3ddc62 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -578,20 +578,12 @@ extern int vt_ioctl(struct tty_struct *tty, struct file *file,
578extern long vt_compat_ioctl(struct tty_struct *tty, struct file * file, 578extern long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
579 unsigned int cmd, unsigned long arg); 579 unsigned int cmd, unsigned long arg);
580 580
581/* tty_mutex.c */
581/* functions for preparation of BKL removal */ 582/* functions for preparation of BKL removal */
582static inline void tty_lock(void) __acquires(kernel_lock) 583extern void __lockfunc tty_lock(void) __acquires(tty_lock);
583{ 584extern void __lockfunc tty_unlock(void) __releases(tty_lock);
584#ifdef CONFIG_LOCK_KERNEL 585extern struct task_struct *__big_tty_mutex_owner;
585 /* kernel_locked is 1 for !CONFIG_LOCK_KERNEL */ 586#define tty_locked() (current == __big_tty_mutex_owner)
586 WARN_ON(kernel_locked());
587#endif
588 lock_kernel();
589}
590static inline void tty_unlock(void) __releases(kernel_lock)
591{
592 unlock_kernel();
593}
594#define tty_locked() (kernel_locked())
595 587
596/* 588/*
597 * wait_event_interruptible_tty -- wait for a condition with the tty lock held 589 * wait_event_interruptible_tty -- wait for a condition with the tty lock held