Commit 5a8da0ea authored by Roland McGrath's avatar Roland McGrath Committed by Linus Torvalds

signals: x86 TS_RESTORE_SIGMASK

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.
Signed-off-by: default avatarRoland McGrath <roland@redhat.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f3de272b
...@@ -128,7 +128,7 @@ asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask) ...@@ -128,7 +128,7 @@ asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
set_thread_flag(TIF_RESTORE_SIGMASK); set_restore_sigmask();
return -ERESTARTNOHAND; return -ERESTARTNOHAND;
} }
......
...@@ -57,7 +57,7 @@ sys_sigsuspend(int history0, int history1, old_sigset_t mask) ...@@ -57,7 +57,7 @@ sys_sigsuspend(int history0, int history1, old_sigset_t mask)
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule(); schedule();
set_thread_flag(TIF_RESTORE_SIGMASK); set_restore_sigmask();
return -ERESTARTNOHAND; return -ERESTARTNOHAND;
} }
...@@ -593,7 +593,7 @@ static void do_signal(struct pt_regs *regs) ...@@ -593,7 +593,7 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs)) if (!user_mode(regs))
return; return;
if (test_thread_flag(TIF_RESTORE_SIGMASK)) if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = &current->saved_sigmask; oldset = &current->saved_sigmask;
else else
oldset = &current->blocked; oldset = &current->blocked;
...@@ -612,13 +612,12 @@ static void do_signal(struct pt_regs *regs) ...@@ -612,13 +612,12 @@ static void do_signal(struct pt_regs *regs)
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
/* /*
* a signal was successfully delivered; the saved * A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame, * sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply * and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag * clear the TS_RESTORE_SIGMASK flag.
*/ */
if (test_thread_flag(TIF_RESTORE_SIGMASK)) current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
clear_thread_flag(TIF_RESTORE_SIGMASK);
} }
return; return;
} }
...@@ -645,8 +644,8 @@ static void do_signal(struct pt_regs *regs) ...@@ -645,8 +644,8 @@ static void do_signal(struct pt_regs *regs)
* If there's no signal to deliver, we just put the saved sigmask * If there's no signal to deliver, we just put the saved sigmask
* back. * back.
*/ */
if (test_thread_flag(TIF_RESTORE_SIGMASK)) { if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
clear_thread_flag(TIF_RESTORE_SIGMASK); current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
} }
} }
...@@ -665,7 +664,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) ...@@ -665,7 +664,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
} }
/* deal with pending signal delivery */ /* deal with pending signal delivery */
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs); do_signal(regs);
if (thread_info_flags & _TIF_HRTICK_RESCHED) if (thread_info_flags & _TIF_HRTICK_RESCHED)
......
...@@ -427,7 +427,7 @@ static void do_signal(struct pt_regs *regs) ...@@ -427,7 +427,7 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs)) if (!user_mode(regs))
return; return;
if (test_thread_flag(TIF_RESTORE_SIGMASK)) if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = &current->saved_sigmask; oldset = &current->saved_sigmask;
else else
oldset = &current->blocked; oldset = &current->blocked;
...@@ -444,11 +444,13 @@ static void do_signal(struct pt_regs *regs) ...@@ -444,11 +444,13 @@ static void do_signal(struct pt_regs *regs)
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
/* a signal was successfully delivered; the saved /*
* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame, * sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply * and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */ * clear the TS_RESTORE_SIGMASK flag.
clear_thread_flag(TIF_RESTORE_SIGMASK); */
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
} }
return; return;
} }
...@@ -476,8 +478,8 @@ static void do_signal(struct pt_regs *regs) ...@@ -476,8 +478,8 @@ static void do_signal(struct pt_regs *regs)
* If there's no signal to deliver, we just put the saved sigmask * If there's no signal to deliver, we just put the saved sigmask
* back. * back.
*/ */
if (test_thread_flag(TIF_RESTORE_SIGMASK)) { if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
clear_thread_flag(TIF_RESTORE_SIGMASK); current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
} }
} }
...@@ -498,7 +500,7 @@ void do_notify_resume(struct pt_regs *regs, void *unused, ...@@ -498,7 +500,7 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
#endif /* CONFIG_X86_MCE */ #endif /* CONFIG_X86_MCE */
/* deal with pending signal delivery */ /* deal with pending signal delivery */
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs); do_signal(regs);
if (thread_info_flags & _TIF_HRTICK_RESCHED) if (thread_info_flags & _TIF_HRTICK_RESCHED)
......
...@@ -131,7 +131,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -131,7 +131,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_EMU 5 /* syscall emulation active */ #define TIF_SYSCALL_EMU 5 /* syscall emulation active */
#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */
#define TIF_SECCOMP 7 /* secure computing */ #define TIF_SECCOMP 7 /* secure computing */
#define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */
#define TIF_HRTICK_RESCHED 9 /* reprogram hrtick timer */ #define TIF_HRTICK_RESCHED 9 /* reprogram hrtick timer */
#define TIF_MEMDIE 16 #define TIF_MEMDIE 16
#define TIF_DEBUG 17 /* uses debug registers */ #define TIF_DEBUG 17 /* uses debug registers */
...@@ -151,7 +150,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -151,7 +150,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED) #define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED)
#define _TIF_DEBUG (1 << TIF_DEBUG) #define _TIF_DEBUG (1 << TIF_DEBUG)
#define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP)
...@@ -188,9 +186,20 @@ static inline struct thread_info *current_thread_info(void) ...@@ -188,9 +186,20 @@ static inline struct thread_info *current_thread_info(void)
this quantum (SMP) */ this quantum (SMP) */
#define TS_POLLING 0x0002 /* True if in idle loop #define TS_POLLING 0x0002 /* True if in idle loop
and not sleeping */ and not sleeping */
#define TS_RESTORE_SIGMASK 0x0004 /* restore signal mask in do_signal() */
#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
#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, &ti->flags);
}
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */ #endif /* _ASM_THREAD_INFO_H */
...@@ -109,7 +109,6 @@ static inline struct thread_info *stack_thread_info(void) ...@@ -109,7 +109,6 @@ static inline struct thread_info *stack_thread_info(void)
#define TIF_IRET 5 /* force IRET */ #define TIF_IRET 5 /* force IRET */
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
#define TIF_SECCOMP 8 /* secure computing */ #define TIF_SECCOMP 8 /* secure computing */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */
#define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */ #define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */
#define TIF_HRTICK_RESCHED 11 /* reprogram hrtick timer */ #define TIF_HRTICK_RESCHED 11 /* reprogram hrtick timer */
/* 16 free */ /* 16 free */
...@@ -133,7 +132,6 @@ static inline struct thread_info *stack_thread_info(void) ...@@ -133,7 +132,6 @@ static inline struct thread_info *stack_thread_info(void)
#define _TIF_IRET (1 << TIF_IRET) #define _TIF_IRET (1 << TIF_IRET)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY) #define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY)
#define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED) #define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED)
#define _TIF_IA32 (1 << TIF_IA32) #define _TIF_IA32 (1 << TIF_IA32)
...@@ -178,9 +176,20 @@ static inline struct thread_info *stack_thread_info(void) ...@@ -178,9 +176,20 @@ static inline struct thread_info *stack_thread_info(void)
#define TS_COMPAT 0x0002 /* 32bit syscall active */ #define TS_COMPAT 0x0002 /* 32bit syscall active */
#define TS_POLLING 0x0004 /* true if in idle loop #define TS_POLLING 0x0004 /* true if in idle loop
and not sleeping */ and not sleeping */
#define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal() */
#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
#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, &ti->flags);
}
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */ #endif /* _ASM_THREAD_INFO_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment