aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:40:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:41 -0400
commit934e6ebf96e8c1a0f299e64129fdaebc1132a427 (patch)
treeab4bd754997b097f06a5cfefd9e3671d56e628f4 /drivers/char
parent2cb5998b5f0ccc886fdda3509059eef297b49577 (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.c18
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(&current->sighand->siglock); 833 spin_unlock_irq(&current->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)
3180struct tty_struct *get_current_tty(void) 3173struct 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(&current->sighand->siglock, flags);
3184 tty = tty_kref_get(current->signal->tty); 3179 tty = tty_kref_get(current->signal->tty);
3185 /* 3180 spin_unlock_irqrestore(&current->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}
3193EXPORT_SYMBOL_GPL(get_current_tty); 3183EXPORT_SYMBOL_GPL(get_current_tty);