diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 05:40:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 12:51:41 -0400 |
commit | 934e6ebf96e8c1a0f299e64129fdaebc1132a427 (patch) | |
tree | ab4bd754997b097f06a5cfefd9e3671d56e628f4 /drivers/char | |
parent | 2cb5998b5f0ccc886fdda3509059eef297b49577 (diff) |
tty: Redo current tty locking
Currently it is sometimes locked by the tty mutex and sometimes by the
sighand lock. The latter is in fact correct and now we can hand back referenced
objects we can fix this up without problems around sleeping functions.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tty_io.c | 18 |
1 files changed, 4 insertions, 14 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index b5f57d0b30ee..f40298e9873a 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -739,13 +739,11 @@ void tty_vhangup_self(void) | |||
739 | { | 739 | { |
740 | struct tty_struct *tty; | 740 | struct tty_struct *tty; |
741 | 741 | ||
742 | mutex_lock(&tty_mutex); | ||
743 | tty = get_current_tty(); | 742 | tty = get_current_tty(); |
744 | if (tty) { | 743 | if (tty) { |
745 | tty_vhangup(tty); | 744 | tty_vhangup(tty); |
746 | tty_kref_put(tty); | 745 | tty_kref_put(tty); |
747 | } | 746 | } |
748 | mutex_unlock(&tty_mutex); | ||
749 | } | 747 | } |
750 | 748 | ||
751 | /** | 749 | /** |
@@ -801,11 +799,9 @@ void disassociate_ctty(int on_exit) | |||
801 | struct pid *tty_pgrp = NULL; | 799 | struct pid *tty_pgrp = NULL; |
802 | 800 | ||
803 | 801 | ||
804 | mutex_lock(&tty_mutex); | ||
805 | tty = get_current_tty(); | 802 | tty = get_current_tty(); |
806 | if (tty) { | 803 | if (tty) { |
807 | tty_pgrp = get_pid(tty->pgrp); | 804 | tty_pgrp = get_pid(tty->pgrp); |
808 | mutex_unlock(&tty_mutex); | ||
809 | lock_kernel(); | 805 | lock_kernel(); |
810 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 806 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
811 | tty_vhangup(tty); | 807 | tty_vhangup(tty); |
@@ -822,7 +818,6 @@ void disassociate_ctty(int on_exit) | |||
822 | kill_pgrp(old_pgrp, SIGCONT, on_exit); | 818 | kill_pgrp(old_pgrp, SIGCONT, on_exit); |
823 | put_pid(old_pgrp); | 819 | put_pid(old_pgrp); |
824 | } | 820 | } |
825 | mutex_unlock(&tty_mutex); | ||
826 | return; | 821 | return; |
827 | } | 822 | } |
828 | if (tty_pgrp) { | 823 | if (tty_pgrp) { |
@@ -837,7 +832,6 @@ void disassociate_ctty(int on_exit) | |||
837 | current->signal->tty_old_pgrp = NULL; | 832 | current->signal->tty_old_pgrp = NULL; |
838 | spin_unlock_irq(¤t->sighand->siglock); | 833 | spin_unlock_irq(¤t->sighand->siglock); |
839 | 834 | ||
840 | mutex_lock(&tty_mutex); | ||
841 | tty = get_current_tty(); | 835 | tty = get_current_tty(); |
842 | if (tty) { | 836 | if (tty) { |
843 | unsigned long flags; | 837 | unsigned long flags; |
@@ -854,7 +848,6 @@ void disassociate_ctty(int on_exit) | |||
854 | " = NULL", tty); | 848 | " = NULL", tty); |
855 | #endif | 849 | #endif |
856 | } | 850 | } |
857 | mutex_unlock(&tty_mutex); | ||
858 | 851 | ||
859 | /* Now clear signal->tty under the lock */ | 852 | /* Now clear signal->tty under the lock */ |
860 | read_lock(&tasklist_lock); | 853 | read_lock(&tasklist_lock); |
@@ -3180,14 +3173,11 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |||
3180 | struct tty_struct *get_current_tty(void) | 3173 | struct tty_struct *get_current_tty(void) |
3181 | { | 3174 | { |
3182 | struct tty_struct *tty; | 3175 | struct tty_struct *tty; |
3183 | WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); | 3176 | unsigned long flags; |
3177 | |||
3178 | spin_lock_irqsave(¤t->sighand->siglock, flags); | ||
3184 | tty = tty_kref_get(current->signal->tty); | 3179 | tty = tty_kref_get(current->signal->tty); |
3185 | /* | 3180 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
3186 | * session->tty can be changed/cleared from under us, make sure we | ||
3187 | * issue the load. The obtained pointer, when not NULL, is valid as | ||
3188 | * long as we hold tty_mutex. | ||
3189 | */ | ||
3190 | barrier(); | ||
3191 | return tty; | 3181 | return tty; |
3192 | } | 3182 | } |
3193 | EXPORT_SYMBOL_GPL(get_current_tty); | 3183 | EXPORT_SYMBOL_GPL(get_current_tty); |