diff options
-rw-r--r-- | drivers/char/Makefile | 1 | ||||
-rw-r--r-- | drivers/char/tty_mutex.c | 47 | ||||
-rw-r--r-- | include/linux/tty.h | 18 |
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 obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o +obj-y += tty_mutex.o obj-$(CONFIG_LEGACY_PTYS) += pty.o obj-$(CONFIG_UNIX98_PTYS) += pty.o obj-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 @@ +/* + * drivers/char/tty_lock.c + */ +#include <linux/tty.h> +#include <linux/module.h> +#include <linux/kallsyms.h> +#include <linux/semaphore.h> +#include <linux/sched.h> + +/* + * The 'big tty mutex' + * + * This mutex is taken and released by tty_lock() and tty_unlock(), + * replacing the older big kernel lock. + * It can no longer be taken recursively, and does not get + * released implicitly while sleeping. + * + * Don't use in new code. + */ +static DEFINE_MUTEX(big_tty_mutex); +struct task_struct *__big_tty_mutex_owner; +EXPORT_SYMBOL_GPL(__big_tty_mutex_owner); + +/* + * Getting the big tty mutex. + */ +void __lockfunc tty_lock(void) +{ + struct task_struct *task = current; + + WARN_ON(__big_tty_mutex_owner == task); + + mutex_lock(&big_tty_mutex); + __big_tty_mutex_owner = task; +} +EXPORT_SYMBOL(tty_lock); + +void __lockfunc tty_unlock(void) +{ + struct task_struct *task = current; + + WARN_ON(__big_tty_mutex_owner != task); + __big_tty_mutex_owner = NULL; + + mutex_unlock(&big_tty_mutex); +} +EXPORT_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, extern long vt_compat_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg); +/* tty_mutex.c */ /* functions for preparation of BKL removal */ -static inline void tty_lock(void) __acquires(kernel_lock) -{ -#ifdef CONFIG_LOCK_KERNEL - /* kernel_locked is 1 for !CONFIG_LOCK_KERNEL */ - WARN_ON(kernel_locked()); -#endif - lock_kernel(); -} -static inline void tty_unlock(void) __releases(kernel_lock) -{ - unlock_kernel(); -} -#define tty_locked() (kernel_locked()) +extern void __lockfunc tty_lock(void) __acquires(tty_lock); +extern void __lockfunc tty_unlock(void) __releases(tty_lock); +extern struct task_struct *__big_tty_mutex_owner; +#define tty_locked() (current == __big_tty_mutex_owner) /* * wait_event_interruptible_tty -- wait for a condition with the tty lock held |