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