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>
This commit is contained in:
Arnd Bergmann
2010-08-06 21:40:30 +02:00
committed by Greg Kroah-Hartman
parent ddcd9fb66a
commit b07471fa51
3 changed files with 53 additions and 13 deletions

47
drivers/char/tty_mutex.c Normal file
View File

@@ -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);