Skip to content

Commit

Permalink
signals: x86 TS_RESTORE_SIGMASK
Browse files Browse the repository at this point in the history
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: Roland 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Roland McGrath authored and Linus Torvalds committed Apr 30, 2008
1 parent f3de272 commit 5a8da0e
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 21 deletions.
2 changes: 1 addition & 1 deletion arch/x86/ia32/ia32_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)

current->state = TASK_INTERRUPTIBLE;
schedule();
set_thread_flag(TIF_RESTORE_SIGMASK);
set_restore_sigmask();
return -ERESTARTNOHAND;
}

Expand Down
17 changes: 8 additions & 9 deletions arch/x86/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ sys_sigsuspend(int history0, int history1, old_sigset_t mask)

current->state = TASK_INTERRUPTIBLE;
schedule();
set_thread_flag(TIF_RESTORE_SIGMASK);
set_restore_sigmask();

return -ERESTARTNOHAND;
}
Expand Down Expand Up @@ -593,7 +593,7 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs))
return;

if (test_thread_flag(TIF_RESTORE_SIGMASK))
if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = &current->saved_sigmask;
else
oldset = &current->blocked;
Expand All @@ -612,13 +612,12 @@ static void do_signal(struct pt_regs *regs)
/* Whee! Actually deliver the signal. */
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,
* 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))
clear_thread_flag(TIF_RESTORE_SIGMASK);
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
}
return;
}
Expand All @@ -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
* 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, &current->saved_sigmask, NULL);
}
}
Expand All @@ -665,7 +664,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
}

/* deal with pending signal delivery */
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs);

if (thread_info_flags & _TIF_HRTICK_RESCHED)
Expand Down
16 changes: 9 additions & 7 deletions arch/x86/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs))
return;

if (test_thread_flag(TIF_RESTORE_SIGMASK))
if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = &current->saved_sigmask;
else
oldset = &current->blocked;
Expand All @@ -444,11 +444,13 @@ static void do_signal(struct pt_regs *regs)

/* Whee! Actually deliver the signal. */
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,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */
clear_thread_flag(TIF_RESTORE_SIGMASK);
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
}
return;
}
Expand Down Expand Up @@ -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
* 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, &current->saved_sigmask, NULL);
}
}
Expand All @@ -498,7 +500,7 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
#endif /* CONFIG_X86_MCE */

/* deal with pending signal delivery */
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs);

if (thread_info_flags & _TIF_HRTICK_RESCHED)
Expand Down
13 changes: 11 additions & 2 deletions include/asm-x86/thread_info_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_EMU 5 /* syscall emulation active */
#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */
#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_MEMDIE 16
#define TIF_DEBUG 17 /* uses debug registers */
Expand All @@ -151,7 +150,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED)
#define _TIF_DEBUG (1 << TIF_DEBUG)
#define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP)
Expand Down Expand Up @@ -188,9 +186,20 @@ static inline struct thread_info *current_thread_info(void)
this quantum (SMP) */
#define TS_POLLING 0x0002 /* True if in idle loop
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)

#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 /* _ASM_THREAD_INFO_H */
13 changes: 11 additions & 2 deletions include/asm-x86/thread_info_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ static inline struct thread_info *stack_thread_info(void)
#define TIF_IRET 5 /* force IRET */
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
#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_HRTICK_RESCHED 11 /* reprogram hrtick timer */
/* 16 free */
Expand All @@ -133,7 +132,6 @@ static inline struct thread_info *stack_thread_info(void)
#define _TIF_IRET (1 << TIF_IRET)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY)
#define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED)
#define _TIF_IA32 (1 << TIF_IA32)
Expand Down Expand Up @@ -178,9 +176,20 @@ static inline struct thread_info *stack_thread_info(void)
#define TS_COMPAT 0x0002 /* 32bit syscall active */
#define TS_POLLING 0x0004 /* true if in idle loop
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)

#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 /* _ASM_THREAD_INFO_H */

0 comments on commit 5a8da0e

Please sign in to comment.