Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh: TS_RESTORE_SIGMASK conversion.

Replace TIF_RESTORE_SIGMASK with TS_RESTORE_SIGMASK and define our own
set_restore_sigmask() function. This saves the costly SMP-safe set_bit
operation, which we do not need for the sigmask flag since TIF_SIGPENDING
always has to be set too.

Based on the x86 and powerpc change.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+44 -23
+22 -4
arch/sh/include/asm/thread_info.h
··· 19 19 struct task_struct *task; /* main task structure */ 20 20 struct exec_domain *exec_domain; /* execution domain */ 21 21 unsigned long flags; /* low level flags */ 22 + __u32 status; /* thread synchronous flags */ 22 23 __u32 cpu; 23 24 int preempt_count; /* 0 => preemptable, <0 => BUG */ 24 25 mm_segment_t addr_limit; /* thread address space */ ··· 112 111 #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 113 112 #define TIF_SIGPENDING 1 /* signal pending */ 114 113 #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ 115 - #define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */ 116 114 #define TIF_SINGLESTEP 4 /* singlestepping active */ 117 115 #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ 118 116 #define TIF_SECCOMP 6 /* secure computing */ ··· 125 125 #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 126 126 #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 127 127 #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 128 - #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 129 128 #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) 130 129 #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) 131 130 #define _TIF_SECCOMP (1 << TIF_SECCOMP) ··· 148 149 /* work to do on any return to u-space */ 149 150 #define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \ 150 151 _TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \ 151 - _TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK | \ 152 - _TIF_NOTIFY_RESUME | _TIF_SYSCALL_TRACEPOINT) 152 + _TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \ 153 + _TIF_SYSCALL_TRACEPOINT) 153 154 154 155 /* work to do on interrupt/exception return */ 155 156 #define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \ 156 157 _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP)) 158 + 159 + /* 160 + * Thread-synchronous status. 161 + * 162 + * This is different from the flags in that nobody else 163 + * ever touches our thread-synchronous status, so we don't 164 + * have to worry about atomic accesses. 165 + */ 166 + #define TS_RESTORE_SIGMASK 0x0001 /* restore signal mask in do_signal() */ 167 + 168 + #ifndef __ASSEMBLY__ 169 + #define HAVE_SET_RESTORE_SIGMASK 1 170 + static inline void set_restore_sigmask(void) 171 + { 172 + struct thread_info *ti = current_thread_info(); 173 + ti->status |= TS_RESTORE_SIGMASK; 174 + set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags); 175 + } 176 + #endif /* !__ASSEMBLY__ */ 157 177 158 178 #endif /* __KERNEL__ */ 159 179
+1 -1
arch/sh/kernel/cpu/sh5/entry.S
··· 933 933 934 934 pta restore_all, tr1 935 935 936 - movi (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8 936 + movi _TIF_SIGPENDING, r8 937 937 and r8, r7, r8 938 938 pta work_notifysig, tr0 939 939 bne r8, ZERO, tr0
+1 -1
arch/sh/kernel/entry-common.S
··· 133 133 ! r8: current_thread_info 134 134 ! t: result of "tst #_TIF_NEED_RESCHED, r0" 135 135 bf/s work_resched 136 - tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 136 + tst #_TIF_SIGPENDING, r0 137 137 work_notifysig: 138 138 bt/s __restore_all 139 139 mov r15, r4
+14 -10
arch/sh/kernel/signal_32.c
··· 67 67 68 68 current->state = TASK_INTERRUPTIBLE; 69 69 schedule(); 70 - set_thread_flag(TIF_RESTORE_SIGMASK); 70 + set_restore_sigmask(); 71 + 71 72 return -ERESTARTNOHAND; 72 73 } 73 74 ··· 591 590 if (try_to_freeze()) 592 591 goto no_signal; 593 592 594 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 593 + if (current_thread_info()->status & TS_RESTORE_SIGMASK) 595 594 oldset = &current->saved_sigmask; 596 595 else 597 596 oldset = &current->blocked; ··· 603 602 /* Whee! Actually deliver the signal. */ 604 603 if (handle_signal(signr, &ka, &info, oldset, 605 604 regs, save_r0) == 0) { 606 - /* a signal was successfully delivered; the saved 605 + /* 606 + * A signal was successfully delivered; the saved 607 607 * sigmask will have been stored in the signal frame, 608 608 * and will be restored by sigreturn, so we can simply 609 - * clear the TIF_RESTORE_SIGMASK flag */ 610 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 611 - clear_thread_flag(TIF_RESTORE_SIGMASK); 609 + * clear the TS_RESTORE_SIGMASK flag 610 + */ 611 + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 612 612 613 613 tracehook_signal_handler(signr, &info, &ka, regs, 614 614 test_thread_flag(TIF_SINGLESTEP)); ··· 633 631 } 634 632 } 635 633 636 - /* if there's no signal to deliver, we just put the saved sigmask 637 - * back */ 638 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 639 - clear_thread_flag(TIF_RESTORE_SIGMASK); 634 + /* 635 + * If there's no signal to deliver, we just put the saved sigmask 636 + * back. 637 + */ 638 + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 639 + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 640 640 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 641 641 } 642 642 }
+6 -7
arch/sh/kernel/signal_64.c
··· 101 101 if (try_to_freeze()) 102 102 goto no_signal; 103 103 104 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 104 + if (current_thread_info()->status & TS_RESTORE_SIGMASK) 105 105 oldset = &current->saved_sigmask; 106 106 else if (!oldset) 107 107 oldset = &current->blocked; ··· 115 115 /* 116 116 * If a signal was successfully delivered, the 117 117 * saved sigmask is in its frame, and we can 118 - * clear the TIF_RESTORE_SIGMASK flag. 118 + * clear the TS_RESTORE_SIGMASK flag. 119 119 */ 120 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 121 - clear_thread_flag(TIF_RESTORE_SIGMASK); 122 - 120 + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 123 121 tracehook_signal_handler(signr, &info, &ka, regs, 0); 124 122 return 1; 125 123 } ··· 144 146 } 145 147 146 148 /* No signal to deliver -- put the saved sigmask back */ 147 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 148 - clear_thread_flag(TIF_RESTORE_SIGMASK); 149 + if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 150 + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 149 151 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 150 152 } 151 153 ··· 174 176 while (1) { 175 177 current->state = TASK_INTERRUPTIBLE; 176 178 schedule(); 179 + set_restore_sigmask(); 177 180 regs->pc += 4; /* because sys_sigreturn decrements the pc */ 178 181 if (do_signal(regs, &saveset)) { 179 182 /* pc now points at signal handler. Need to decrement