diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-02 18:21:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-02 18:21:43 -0400 |
commit | f309532bf3e1cc1b787403d84e3039812a7dbe50 (patch) | |
tree | 6508ac81e94bfc137d1d9a55b973a2e0e0ac007b /drivers/tty/tty_ldisc.c | |
parent | 233e562eac549f4f719176bbddeb50c3f17a9c8d (diff) |
tty: Revert the tty locking series, it needs more work
This reverts the tty layer change to use per-tty locking, because it's
not correct yet, and fixing it will require some more deep surgery.
The main revert is d29f3ef39be4 ("tty_lock: Localise the lock"), but
there are several smaller commits that built upon it, they also get
reverted here. The list of reverted commits is:
fde86d310886 - tty: add lockdep annotations
8f6576ad476b - tty: fix ldisc lock inversion trace
d3ca8b64b97e - pty: Fix lock inversion
b1d679afd766 - tty: drop the pty lock during hangup
abcefe5fc357 - tty/amiserial: Add missing argument for tty_unlock()
fd11b42e3598 - cris: fix missing tty arg in wait_event_interruptible_tty call
d29f3ef39be4 - tty_lock: Localise the lock
The revert had a trivial conflict in the 68360serial.c staging driver
that got removed in the meantime.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/tty/tty_ldisc.c')
-rw-r--r-- | drivers/tty/tty_ldisc.c | 67 |
1 files changed, 29 insertions, 38 deletions
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index ba8be396a621..9911eb6b34cd 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -568,7 +568,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
568 | if (IS_ERR(new_ldisc)) | 568 | if (IS_ERR(new_ldisc)) |
569 | return PTR_ERR(new_ldisc); | 569 | return PTR_ERR(new_ldisc); |
570 | 570 | ||
571 | tty_lock(tty); | 571 | tty_lock(); |
572 | /* | 572 | /* |
573 | * We need to look at the tty locking here for pty/tty pairs | 573 | * We need to look at the tty locking here for pty/tty pairs |
574 | * when both sides try to change in parallel. | 574 | * when both sides try to change in parallel. |
@@ -582,12 +582,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
582 | */ | 582 | */ |
583 | 583 | ||
584 | if (tty->ldisc->ops->num == ldisc) { | 584 | if (tty->ldisc->ops->num == ldisc) { |
585 | tty_unlock(tty); | 585 | tty_unlock(); |
586 | tty_ldisc_put(new_ldisc); | 586 | tty_ldisc_put(new_ldisc); |
587 | return 0; | 587 | return 0; |
588 | } | 588 | } |
589 | 589 | ||
590 | tty_unlock(tty); | 590 | tty_unlock(); |
591 | /* | 591 | /* |
592 | * Problem: What do we do if this blocks ? | 592 | * Problem: What do we do if this blocks ? |
593 | * We could deadlock here | 593 | * We could deadlock here |
@@ -595,7 +595,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
595 | 595 | ||
596 | tty_wait_until_sent(tty, 0); | 596 | tty_wait_until_sent(tty, 0); |
597 | 597 | ||
598 | tty_lock(tty); | 598 | tty_lock(); |
599 | mutex_lock(&tty->ldisc_mutex); | 599 | mutex_lock(&tty->ldisc_mutex); |
600 | 600 | ||
601 | /* | 601 | /* |
@@ -605,10 +605,10 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
605 | 605 | ||
606 | while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { | 606 | while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { |
607 | mutex_unlock(&tty->ldisc_mutex); | 607 | mutex_unlock(&tty->ldisc_mutex); |
608 | tty_unlock(tty); | 608 | tty_unlock(); |
609 | wait_event(tty_ldisc_wait, | 609 | wait_event(tty_ldisc_wait, |
610 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); | 610 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); |
611 | tty_lock(tty); | 611 | tty_lock(); |
612 | mutex_lock(&tty->ldisc_mutex); | 612 | mutex_lock(&tty->ldisc_mutex); |
613 | } | 613 | } |
614 | 614 | ||
@@ -623,7 +623,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
623 | 623 | ||
624 | o_ldisc = tty->ldisc; | 624 | o_ldisc = tty->ldisc; |
625 | 625 | ||
626 | tty_unlock(tty); | 626 | tty_unlock(); |
627 | /* | 627 | /* |
628 | * Make sure we don't change while someone holds a | 628 | * Make sure we don't change while someone holds a |
629 | * reference to the line discipline. The TTY_LDISC bit | 629 | * reference to the line discipline. The TTY_LDISC bit |
@@ -650,7 +650,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
650 | 650 | ||
651 | retval = tty_ldisc_wait_idle(tty, 5 * HZ); | 651 | retval = tty_ldisc_wait_idle(tty, 5 * HZ); |
652 | 652 | ||
653 | tty_lock(tty); | 653 | tty_lock(); |
654 | mutex_lock(&tty->ldisc_mutex); | 654 | mutex_lock(&tty->ldisc_mutex); |
655 | 655 | ||
656 | /* handle wait idle failure locked */ | 656 | /* handle wait idle failure locked */ |
@@ -665,7 +665,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
665 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 665 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
666 | mutex_unlock(&tty->ldisc_mutex); | 666 | mutex_unlock(&tty->ldisc_mutex); |
667 | tty_ldisc_put(new_ldisc); | 667 | tty_ldisc_put(new_ldisc); |
668 | tty_unlock(tty); | 668 | tty_unlock(); |
669 | return -EIO; | 669 | return -EIO; |
670 | } | 670 | } |
671 | 671 | ||
@@ -708,7 +708,7 @@ enable: | |||
708 | if (o_work) | 708 | if (o_work) |
709 | schedule_work(&o_tty->buf.work); | 709 | schedule_work(&o_tty->buf.work); |
710 | mutex_unlock(&tty->ldisc_mutex); | 710 | mutex_unlock(&tty->ldisc_mutex); |
711 | tty_unlock(tty); | 711 | tty_unlock(); |
712 | return retval; | 712 | return retval; |
713 | } | 713 | } |
714 | 714 | ||
@@ -816,11 +816,11 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
816 | * need to wait for another function taking the BTM | 816 | * need to wait for another function taking the BTM |
817 | */ | 817 | */ |
818 | clear_bit(TTY_LDISC, &tty->flags); | 818 | clear_bit(TTY_LDISC, &tty->flags); |
819 | tty_unlock(tty); | 819 | tty_unlock(); |
820 | cancel_work_sync(&tty->buf.work); | 820 | cancel_work_sync(&tty->buf.work); |
821 | mutex_unlock(&tty->ldisc_mutex); | 821 | mutex_unlock(&tty->ldisc_mutex); |
822 | retry: | 822 | retry: |
823 | tty_lock(tty); | 823 | tty_lock(); |
824 | mutex_lock(&tty->ldisc_mutex); | 824 | mutex_lock(&tty->ldisc_mutex); |
825 | 825 | ||
826 | /* At this point we have a closed ldisc and we want to | 826 | /* At this point we have a closed ldisc and we want to |
@@ -831,7 +831,7 @@ retry: | |||
831 | if (atomic_read(&tty->ldisc->users) != 1) { | 831 | if (atomic_read(&tty->ldisc->users) != 1) { |
832 | char cur_n[TASK_COMM_LEN], tty_n[64]; | 832 | char cur_n[TASK_COMM_LEN], tty_n[64]; |
833 | long timeout = 3 * HZ; | 833 | long timeout = 3 * HZ; |
834 | tty_unlock(tty); | 834 | tty_unlock(); |
835 | 835 | ||
836 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { | 836 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { |
837 | timeout = MAX_SCHEDULE_TIMEOUT; | 837 | timeout = MAX_SCHEDULE_TIMEOUT; |
@@ -894,23 +894,6 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) | |||
894 | tty_ldisc_enable(tty); | 894 | tty_ldisc_enable(tty); |
895 | return 0; | 895 | return 0; |
896 | } | 896 | } |
897 | |||
898 | static void tty_ldisc_kill(struct tty_struct *tty) | ||
899 | { | ||
900 | mutex_lock(&tty->ldisc_mutex); | ||
901 | /* | ||
902 | * Now kill off the ldisc | ||
903 | */ | ||
904 | tty_ldisc_close(tty, tty->ldisc); | ||
905 | tty_ldisc_put(tty->ldisc); | ||
906 | /* Force an oops if we mess this up */ | ||
907 | tty->ldisc = NULL; | ||
908 | |||
909 | /* Ensure the next open requests the N_TTY ldisc */ | ||
910 | tty_set_termios_ldisc(tty, N_TTY); | ||
911 | mutex_unlock(&tty->ldisc_mutex); | ||
912 | } | ||
913 | |||
914 | /** | 897 | /** |
915 | * tty_ldisc_release - release line discipline | 898 | * tty_ldisc_release - release line discipline |
916 | * @tty: tty being shut down | 899 | * @tty: tty being shut down |
@@ -929,19 +912,27 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
929 | * race with the set_ldisc code path. | 912 | * race with the set_ldisc code path. |
930 | */ | 913 | */ |
931 | 914 | ||
932 | tty_unlock_pair(tty, o_tty); | 915 | tty_unlock(); |
933 | tty_ldisc_halt(tty); | 916 | tty_ldisc_halt(tty); |
934 | tty_ldisc_flush_works(tty); | 917 | tty_ldisc_flush_works(tty); |
935 | if (o_tty) { | 918 | tty_lock(); |
936 | tty_ldisc_halt(o_tty); | ||
937 | tty_ldisc_flush_works(o_tty); | ||
938 | } | ||
939 | tty_lock_pair(tty, o_tty); | ||
940 | 919 | ||
920 | mutex_lock(&tty->ldisc_mutex); | ||
921 | /* | ||
922 | * Now kill off the ldisc | ||
923 | */ | ||
924 | tty_ldisc_close(tty, tty->ldisc); | ||
925 | tty_ldisc_put(tty->ldisc); | ||
926 | /* Force an oops if we mess this up */ | ||
927 | tty->ldisc = NULL; | ||
928 | |||
929 | /* Ensure the next open requests the N_TTY ldisc */ | ||
930 | tty_set_termios_ldisc(tty, N_TTY); | ||
931 | mutex_unlock(&tty->ldisc_mutex); | ||
941 | 932 | ||
942 | tty_ldisc_kill(tty); | 933 | /* This will need doing differently if we need to lock */ |
943 | if (o_tty) | 934 | if (o_tty) |
944 | tty_ldisc_kill(o_tty); | 935 | tty_ldisc_release(o_tty, NULL); |
945 | 936 | ||
946 | /* And the memory resources remaining (buffers, termios) will be | 937 | /* And the memory resources remaining (buffers, termios) will be |
947 | disposed of when the kref hits zero */ | 938 | disposed of when the kref hits zero */ |