diff options
Diffstat (limited to 'drivers/tty/tty_mutex.c')
| -rw-r--r-- | drivers/tty/tty_mutex.c | 71 |
1 files changed, 56 insertions, 15 deletions
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 9ff986c32a21..67feac9e6ebb 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
| @@ -4,29 +4,70 @@ | |||
| 4 | #include <linux/semaphore.h> | 4 | #include <linux/semaphore.h> |
| 5 | #include <linux/sched.h> | 5 | #include <linux/sched.h> |
| 6 | 6 | ||
| 7 | /* | 7 | /* Legacy tty mutex glue */ |
| 8 | * The 'big tty mutex' | 8 | |
| 9 | * | 9 | enum { |
| 10 | * This mutex is taken and released by tty_lock() and tty_unlock(), | 10 | TTY_MUTEX_NORMAL, |
| 11 | * replacing the older big kernel lock. | 11 | TTY_MUTEX_NESTED, |
| 12 | * It can no longer be taken recursively, and does not get | 12 | }; |
| 13 | * released implicitly while sleeping. | ||
| 14 | * | ||
| 15 | * Don't use in new code. | ||
| 16 | */ | ||
| 17 | static DEFINE_MUTEX(big_tty_mutex); | ||
| 18 | 13 | ||
| 19 | /* | 14 | /* |
| 20 | * Getting the big tty mutex. | 15 | * Getting the big tty mutex. |
| 21 | */ | 16 | */ |
| 22 | void __lockfunc tty_lock(void) | 17 | |
| 18 | static void __lockfunc tty_lock_nested(struct tty_struct *tty, | ||
| 19 | unsigned int subclass) | ||
| 23 | { | 20 | { |
| 24 | mutex_lock(&big_tty_mutex); | 21 | if (tty->magic != TTY_MAGIC) { |
| 22 | printk(KERN_ERR "L Bad %p\n", tty); | ||
| 23 | WARN_ON(1); | ||
| 24 | return; | ||
| 25 | } | ||
| 26 | tty_kref_get(tty); | ||
| 27 | mutex_lock_nested(&tty->legacy_mutex, subclass); | ||
| 28 | } | ||
| 29 | |||
| 30 | void __lockfunc tty_lock(struct tty_struct *tty) | ||
| 31 | { | ||
| 32 | return tty_lock_nested(tty, TTY_MUTEX_NORMAL); | ||
| 25 | } | 33 | } |
| 26 | EXPORT_SYMBOL(tty_lock); | 34 | EXPORT_SYMBOL(tty_lock); |
| 27 | 35 | ||
| 28 | void __lockfunc tty_unlock(void) | 36 | void __lockfunc tty_unlock(struct tty_struct *tty) |
| 29 | { | 37 | { |
| 30 | mutex_unlock(&big_tty_mutex); | 38 | if (tty->magic != TTY_MAGIC) { |
| 39 | printk(KERN_ERR "U Bad %p\n", tty); | ||
| 40 | WARN_ON(1); | ||
| 41 | return; | ||
| 42 | } | ||
| 43 | mutex_unlock(&tty->legacy_mutex); | ||
| 44 | tty_kref_put(tty); | ||
| 31 | } | 45 | } |
| 32 | EXPORT_SYMBOL(tty_unlock); | 46 | EXPORT_SYMBOL(tty_unlock); |
| 47 | |||
| 48 | /* | ||
| 49 | * Getting the big tty mutex for a pair of ttys with lock ordering | ||
| 50 | * On a non pty/tty pair tty2 can be NULL which is just fine. | ||
| 51 | */ | ||
| 52 | void __lockfunc tty_lock_pair(struct tty_struct *tty, | ||
| 53 | struct tty_struct *tty2) | ||
| 54 | { | ||
| 55 | if (tty < tty2) { | ||
| 56 | tty_lock(tty); | ||
| 57 | tty_lock_nested(tty2, TTY_MUTEX_NESTED); | ||
| 58 | } else { | ||
| 59 | if (tty2 && tty2 != tty) | ||
| 60 | tty_lock(tty2); | ||
| 61 | tty_lock_nested(tty, TTY_MUTEX_NESTED); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | EXPORT_SYMBOL(tty_lock_pair); | ||
| 65 | |||
| 66 | void __lockfunc tty_unlock_pair(struct tty_struct *tty, | ||
| 67 | struct tty_struct *tty2) | ||
| 68 | { | ||
| 69 | tty_unlock(tty); | ||
| 70 | if (tty2 && tty2 != tty) | ||
| 71 | tty_unlock(tty2); | ||
| 72 | } | ||
| 73 | EXPORT_SYMBOL(tty_unlock_pair); | ||
