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>
This commit is contained in:
Родитель
b195e46677
Коммит
56bfc42f6c
|
@ -19,6 +19,7 @@ struct thread_info {
|
|||
struct task_struct *task; /* main task structure */
|
||||
struct exec_domain *exec_domain; /* execution domain */
|
||||
unsigned long flags; /* low level flags */
|
||||
__u32 status; /* thread synchronous flags */
|
||||
__u32 cpu;
|
||||
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
||||
mm_segment_t addr_limit; /* thread address space */
|
||||
|
@ -111,7 +112,6 @@ extern void free_thread_info(struct thread_info *ti);
|
|||
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
|
||||
#define TIF_SIGPENDING 1 /* signal pending */
|
||||
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
|
||||
#define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */
|
||||
#define TIF_SINGLESTEP 4 /* singlestepping active */
|
||||
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
|
||||
#define TIF_SECCOMP 6 /* secure computing */
|
||||
|
@ -125,7 +125,6 @@ extern void free_thread_info(struct thread_info *ti);
|
|||
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
|
||||
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
||||
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
|
||||
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
|
||||
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
|
||||
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
|
||||
|
@ -149,13 +148,32 @@ extern void free_thread_info(struct thread_info *ti);
|
|||
/* work to do on any return to u-space */
|
||||
#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \
|
||||
_TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \
|
||||
_TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK | \
|
||||
_TIF_NOTIFY_RESUME | _TIF_SYSCALL_TRACEPOINT)
|
||||
_TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \
|
||||
_TIF_SYSCALL_TRACEPOINT)
|
||||
|
||||
/* work to do on interrupt/exception return */
|
||||
#define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
|
||||
_TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
|
||||
|
||||
/*
|
||||
* Thread-synchronous status.
|
||||
*
|
||||
* This is different from the flags in that nobody else
|
||||
* ever touches our thread-synchronous status, so we don't
|
||||
* have to worry about atomic accesses.
|
||||
*/
|
||||
#define TS_RESTORE_SIGMASK 0x0001 /* restore signal mask in do_signal() */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define HAVE_SET_RESTORE_SIGMASK 1
|
||||
static inline void set_restore_sigmask(void)
|
||||
{
|
||||
struct thread_info *ti = current_thread_info();
|
||||
ti->status |= TS_RESTORE_SIGMASK;
|
||||
set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags);
|
||||
}
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ASM_SH_THREAD_INFO_H */
|
||||
|
|
|
@ -933,7 +933,7 @@ ret_with_reschedule:
|
|||
|
||||
pta restore_all, tr1
|
||||
|
||||
movi (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8
|
||||
movi _TIF_SIGPENDING, r8
|
||||
and r8, r7, r8
|
||||
pta work_notifysig, tr0
|
||||
bne r8, ZERO, tr0
|
||||
|
|
|
@ -133,7 +133,7 @@ work_pending:
|
|||
! r8: current_thread_info
|
||||
! t: result of "tst #_TIF_NEED_RESCHED, r0"
|
||||
bf/s work_resched
|
||||
tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0
|
||||
tst #_TIF_SIGPENDING, r0
|
||||
work_notifysig:
|
||||
bt/s __restore_all
|
||||
mov r15, r4
|
||||
|
|
|
@ -67,7 +67,8 @@ sys_sigsuspend(old_sigset_t mask,
|
|||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
set_restore_sigmask();
|
||||
|
||||
return -ERESTARTNOHAND;
|
||||
}
|
||||
|
||||
|
@ -590,7 +591,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
|
|||
if (try_to_freeze())
|
||||
goto no_signal;
|
||||
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
if (current_thread_info()->status & TS_RESTORE_SIGMASK)
|
||||
oldset = ¤t->saved_sigmask;
|
||||
else
|
||||
oldset = ¤t->blocked;
|
||||
|
@ -602,12 +603,13 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
|
|||
/* Whee! Actually deliver the signal. */
|
||||
if (handle_signal(signr, &ka, &info, oldset,
|
||||
regs, save_r0) == 0) {
|
||||
/* a signal was successfully delivered; the saved
|
||||
/*
|
||||
* A signal was successfully delivered; the saved
|
||||
* sigmask will have been stored in the signal frame,
|
||||
* and will be restored by sigreturn, so we can simply
|
||||
* clear the TIF_RESTORE_SIGMASK flag */
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
* clear the TS_RESTORE_SIGMASK flag
|
||||
*/
|
||||
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
|
||||
|
||||
tracehook_signal_handler(signr, &info, &ka, regs,
|
||||
test_thread_flag(TIF_SINGLESTEP));
|
||||
|
@ -631,10 +633,12 @@ no_signal:
|
|||
}
|
||||
}
|
||||
|
||||
/* if there's no signal to deliver, we just put the saved sigmask
|
||||
* back */
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
/*
|
||||
* If there's no signal to deliver, we just put the saved sigmask
|
||||
* back.
|
||||
*/
|
||||
if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
|
||||
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
|
||||
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
|
|||
if (try_to_freeze())
|
||||
goto no_signal;
|
||||
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
if (current_thread_info()->status & TS_RESTORE_SIGMASK)
|
||||
oldset = ¤t->saved_sigmask;
|
||||
else if (!oldset)
|
||||
oldset = ¤t->blocked;
|
||||
|
@ -115,11 +115,9 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
|
|||
/*
|
||||
* If a signal was successfully delivered, the
|
||||
* saved sigmask is in its frame, and we can
|
||||
* clear the TIF_RESTORE_SIGMASK flag.
|
||||
* clear the TS_RESTORE_SIGMASK flag.
|
||||
*/
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
|
||||
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
|
||||
tracehook_signal_handler(signr, &info, &ka, regs, 0);
|
||||
return 1;
|
||||
}
|
||||
|
@ -146,8 +144,8 @@ no_signal:
|
|||
}
|
||||
|
||||
/* No signal to deliver -- put the saved sigmask back */
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
|
||||
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
|
||||
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
||||
}
|
||||
|
||||
|
@ -176,6 +174,7 @@ sys_sigsuspend(old_sigset_t mask,
|
|||
while (1) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
regs->pc += 4; /* because sys_sigreturn decrements the pc */
|
||||
if (do_signal(regs, &saveset)) {
|
||||
/* pc now points at signal handler. Need to decrement
|
||||
|
|
Загрузка…
Ссылка в новой задаче