Commit 9b429620740945363b746414e8b9a84b8119914c
Committed by
H. Peter Anvin
1 parent
3982294b03
Exists in
master
and in
6 other branches
x86, do_signal: Simplify the TS_RESTORE_SIGMASK logic
1. do_signal() looks at TS_RESTORE_SIGMASK and calculates the mask which should be stored in the signal frame, then it passes "oldset" to the callees, down to setup_rt_frame(). This is ugly, setup_rt_frame() can do this itself and nobody else needs this sigset_t. Move this code into setup_rt_frame. 2. do_signal() also clears TS_RESTORE_SIGMASK if handle_signal() succeeds. We can move this to setup_rt_frame() as well, this avoids the unnecessary checks and makes the logic more clear. 3. use set_current_blocked() instead of sigprocmask(SIG_SETMASK), sigprocmask() should be avoided. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Link: http://lkml.kernel.org/r/20110710182203.GA27979@redhat.com Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Showing 1 changed file with 10 additions and 19 deletions Side-by-side Diff
arch/x86/kernel/signal.c
... | ... | @@ -651,11 +651,15 @@ |
651 | 651 | |
652 | 652 | static int |
653 | 653 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
654 | - sigset_t *set, struct pt_regs *regs) | |
654 | + struct pt_regs *regs) | |
655 | 655 | { |
656 | 656 | int usig = signr_convert(sig); |
657 | + sigset_t *set = ¤t->blocked; | |
657 | 658 | int ret; |
658 | 659 | |
660 | + if (current_thread_info()->status & TS_RESTORE_SIGMASK) | |
661 | + set = ¤t->saved_sigmask; | |
662 | + | |
659 | 663 | /* Set up the stack frame */ |
660 | 664 | if (is_ia32) { |
661 | 665 | if (ka->sa.sa_flags & SA_SIGINFO) |
662 | 666 | |
... | ... | @@ -670,12 +674,13 @@ |
670 | 674 | return -EFAULT; |
671 | 675 | } |
672 | 676 | |
677 | + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | |
673 | 678 | return ret; |
674 | 679 | } |
675 | 680 | |
676 | 681 | static int |
677 | 682 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
678 | - sigset_t *oldset, struct pt_regs *regs) | |
683 | + struct pt_regs *regs) | |
679 | 684 | { |
680 | 685 | sigset_t blocked; |
681 | 686 | int ret; |
... | ... | @@ -710,7 +715,7 @@ |
710 | 715 | likely(test_and_clear_thread_flag(TIF_FORCED_TF))) |
711 | 716 | regs->flags &= ~X86_EFLAGS_TF; |
712 | 717 | |
713 | - ret = setup_rt_frame(sig, ka, info, oldset, regs); | |
718 | + ret = setup_rt_frame(sig, ka, info, regs); | |
714 | 719 | |
715 | 720 | if (ret) |
716 | 721 | return ret; |
... | ... | @@ -765,7 +770,6 @@ |
765 | 770 | struct k_sigaction ka; |
766 | 771 | siginfo_t info; |
767 | 772 | int signr; |
768 | - sigset_t *oldset; | |
769 | 773 | |
770 | 774 | /* |
771 | 775 | * We want the common case to go fast, which is why we may in certain |
772 | 776 | |
... | ... | @@ -777,23 +781,10 @@ |
777 | 781 | if (!user_mode(regs)) |
778 | 782 | return; |
779 | 783 | |
780 | - if (current_thread_info()->status & TS_RESTORE_SIGMASK) | |
781 | - oldset = ¤t->saved_sigmask; | |
782 | - else | |
783 | - oldset = ¤t->blocked; | |
784 | - | |
785 | 784 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
786 | 785 | if (signr > 0) { |
787 | 786 | /* Whee! Actually deliver the signal. */ |
788 | - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | |
789 | - /* | |
790 | - * A signal was successfully delivered; the saved | |
791 | - * sigmask will have been stored in the signal frame, | |
792 | - * and will be restored by sigreturn, so we can simply | |
793 | - * clear the TS_RESTORE_SIGMASK flag. | |
794 | - */ | |
795 | - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | |
796 | - } | |
787 | + handle_signal(signr, &info, &ka, regs); | |
797 | 788 | return; |
798 | 789 | } |
799 | 790 | |
... | ... | @@ -821,7 +812,7 @@ |
821 | 812 | */ |
822 | 813 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { |
823 | 814 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
824 | - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | |
815 | + set_current_blocked(¤t->saved_sigmask); | |
825 | 816 | } |
826 | 817 | } |
827 | 818 |