diff options
author | Roland McGrath <roland@redhat.com> | 2008-04-30 03:53:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:37 -0400 |
commit | 5a8da0ea82db6fa9737041381079fd16f25dcce2 (patch) | |
tree | abd26177c0a965315de290e1e9602d087b78f149 | |
parent | f3de272b821accbc8387211977c2de4f38468d05 (diff) |
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: 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>
-rw-r--r-- | arch/x86/ia32/ia32_signal.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/signal_32.c | 17 | ||||
-rw-r--r-- | arch/x86/kernel/signal_64.c | 16 | ||||
-rw-r--r-- | include/asm-x86/thread_info_32.h | 13 | ||||
-rw-r--r-- | include/asm-x86/thread_info_64.h | 13 |
5 files changed, 40 insertions, 21 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index bbed3a26ce55..cb3856a18c85 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c | |||
@@ -128,7 +128,7 @@ asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask) | |||
128 | 128 | ||
129 | current->state = TASK_INTERRUPTIBLE; | 129 | current->state = TASK_INTERRUPTIBLE; |
130 | schedule(); | 130 | schedule(); |
131 | set_thread_flag(TIF_RESTORE_SIGMASK); | 131 | set_restore_sigmask(); |
132 | return -ERESTARTNOHAND; | 132 | return -ERESTARTNOHAND; |
133 | } | 133 | } |
134 | 134 | ||
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index 8e05e7f7bd40..d92373630963 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c | |||
@@ -57,7 +57,7 @@ sys_sigsuspend(int history0, int history1, old_sigset_t mask) | |||
57 | 57 | ||
58 | current->state = TASK_INTERRUPTIBLE; | 58 | current->state = TASK_INTERRUPTIBLE; |
59 | schedule(); | 59 | schedule(); |
60 | set_thread_flag(TIF_RESTORE_SIGMASK); | 60 | set_restore_sigmask(); |
61 | 61 | ||
62 | return -ERESTARTNOHAND; | 62 | return -ERESTARTNOHAND; |
63 | } | 63 | } |
@@ -593,7 +593,7 @@ static void do_signal(struct pt_regs *regs) | |||
593 | if (!user_mode(regs)) | 593 | if (!user_mode(regs)) |
594 | return; | 594 | return; |
595 | 595 | ||
596 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 596 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) |
597 | oldset = ¤t->saved_sigmask; | 597 | oldset = ¤t->saved_sigmask; |
598 | else | 598 | else |
599 | oldset = ¤t->blocked; | 599 | oldset = ¤t->blocked; |
@@ -612,13 +612,12 @@ static void do_signal(struct pt_regs *regs) | |||
612 | /* Whee! Actually deliver the signal. */ | 612 | /* Whee! Actually deliver the signal. */ |
613 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 613 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { |
614 | /* | 614 | /* |
615 | * a signal was successfully delivered; the saved | 615 | * A signal was successfully delivered; the saved |
616 | * sigmask will have been stored in the signal frame, | 616 | * sigmask will have been stored in the signal frame, |
617 | * and will be restored by sigreturn, so we can simply | 617 | * and will be restored by sigreturn, so we can simply |
618 | * clear the TIF_RESTORE_SIGMASK flag | 618 | * clear the TS_RESTORE_SIGMASK flag. |
619 | */ | 619 | */ |
620 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 620 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
621 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
622 | } | 621 | } |
623 | return; | 622 | return; |
624 | } | 623 | } |
@@ -645,8 +644,8 @@ static void do_signal(struct pt_regs *regs) | |||
645 | * If there's no signal to deliver, we just put the saved sigmask | 644 | * If there's no signal to deliver, we just put the saved sigmask |
646 | * back. | 645 | * back. |
647 | */ | 646 | */ |
648 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 647 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { |
649 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 648 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
650 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 649 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
651 | } | 650 | } |
652 | } | 651 | } |
@@ -665,7 +664,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | |||
665 | } | 664 | } |
666 | 665 | ||
667 | /* deal with pending signal delivery */ | 666 | /* deal with pending signal delivery */ |
668 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 667 | if (thread_info_flags & _TIF_SIGPENDING) |
669 | do_signal(regs); | 668 | do_signal(regs); |
670 | 669 | ||
671 | if (thread_info_flags & _TIF_HRTICK_RESCHED) | 670 | if (thread_info_flags & _TIF_HRTICK_RESCHED) |
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index ccb2a4560c2d..e53b267662e7 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -427,7 +427,7 @@ static void do_signal(struct pt_regs *regs) | |||
427 | if (!user_mode(regs)) | 427 | if (!user_mode(regs)) |
428 | return; | 428 | return; |
429 | 429 | ||
430 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 430 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) |
431 | oldset = ¤t->saved_sigmask; | 431 | oldset = ¤t->saved_sigmask; |
432 | else | 432 | else |
433 | oldset = ¤t->blocked; | 433 | oldset = ¤t->blocked; |
@@ -444,11 +444,13 @@ static void do_signal(struct pt_regs *regs) | |||
444 | 444 | ||
445 | /* Whee! Actually deliver the signal. */ | 445 | /* Whee! Actually deliver the signal. */ |
446 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 446 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { |
447 | /* a signal was successfully delivered; the saved | 447 | /* |
448 | * A signal was successfully delivered; the saved | ||
448 | * sigmask will have been stored in the signal frame, | 449 | * sigmask will have been stored in the signal frame, |
449 | * and will be restored by sigreturn, so we can simply | 450 | * and will be restored by sigreturn, so we can simply |
450 | * clear the TIF_RESTORE_SIGMASK flag */ | 451 | * clear the TS_RESTORE_SIGMASK flag. |
451 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 452 | */ |
453 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | ||
452 | } | 454 | } |
453 | return; | 455 | return; |
454 | } | 456 | } |
@@ -476,8 +478,8 @@ static void do_signal(struct pt_regs *regs) | |||
476 | * If there's no signal to deliver, we just put the saved sigmask | 478 | * If there's no signal to deliver, we just put the saved sigmask |
477 | * back. | 479 | * back. |
478 | */ | 480 | */ |
479 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 481 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { |
480 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 482 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
481 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 483 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
482 | } | 484 | } |
483 | } | 485 | } |
@@ -498,7 +500,7 @@ void do_notify_resume(struct pt_regs *regs, void *unused, | |||
498 | #endif /* CONFIG_X86_MCE */ | 500 | #endif /* CONFIG_X86_MCE */ |
499 | 501 | ||
500 | /* deal with pending signal delivery */ | 502 | /* deal with pending signal delivery */ |
501 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 503 | if (thread_info_flags & _TIF_SIGPENDING) |
502 | do_signal(regs); | 504 | do_signal(regs); |
503 | 505 | ||
504 | if (thread_info_flags & _TIF_HRTICK_RESCHED) | 506 | if (thread_info_flags & _TIF_HRTICK_RESCHED) |
diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h index 531859962096..b6338829d1a8 100644 --- a/include/asm-x86/thread_info_32.h +++ b/include/asm-x86/thread_info_32.h | |||
@@ -131,7 +131,6 @@ static inline struct thread_info *current_thread_info(void) | |||
131 | #define TIF_SYSCALL_EMU 5 /* syscall emulation active */ | 131 | #define TIF_SYSCALL_EMU 5 /* syscall emulation active */ |
132 | #define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */ | 132 | #define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */ |
133 | #define TIF_SECCOMP 7 /* secure computing */ | 133 | #define TIF_SECCOMP 7 /* secure computing */ |
134 | #define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */ | ||
135 | #define TIF_HRTICK_RESCHED 9 /* reprogram hrtick timer */ | 134 | #define TIF_HRTICK_RESCHED 9 /* reprogram hrtick timer */ |
136 | #define TIF_MEMDIE 16 | 135 | #define TIF_MEMDIE 16 |
137 | #define TIF_DEBUG 17 /* uses debug registers */ | 136 | #define TIF_DEBUG 17 /* uses debug registers */ |
@@ -151,7 +150,6 @@ static inline struct thread_info *current_thread_info(void) | |||
151 | #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) | 150 | #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) |
152 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) | 151 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) |
153 | #define _TIF_SECCOMP (1 << TIF_SECCOMP) | 152 | #define _TIF_SECCOMP (1 << TIF_SECCOMP) |
154 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) | ||
155 | #define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED) | 153 | #define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED) |
156 | #define _TIF_DEBUG (1 << TIF_DEBUG) | 154 | #define _TIF_DEBUG (1 << TIF_DEBUG) |
157 | #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) | 155 | #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) |
@@ -188,9 +186,20 @@ static inline struct thread_info *current_thread_info(void) | |||
188 | this quantum (SMP) */ | 186 | this quantum (SMP) */ |
189 | #define TS_POLLING 0x0002 /* True if in idle loop | 187 | #define TS_POLLING 0x0002 /* True if in idle loop |
190 | and not sleeping */ | 188 | and not sleeping */ |
189 | #define TS_RESTORE_SIGMASK 0x0004 /* restore signal mask in do_signal() */ | ||
191 | 190 | ||
192 | #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) | 191 | #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) |
193 | 192 | ||
193 | #ifndef __ASSEMBLY__ | ||
194 | #define HAVE_SET_RESTORE_SIGMASK 1 | ||
195 | static inline void set_restore_sigmask(void) | ||
196 | { | ||
197 | struct thread_info *ti = current_thread_info(); | ||
198 | ti->status |= TS_RESTORE_SIGMASK; | ||
199 | set_bit(TIF_SIGPENDING, &ti->flags); | ||
200 | } | ||
201 | #endif /* !__ASSEMBLY__ */ | ||
202 | |||
194 | #endif /* __KERNEL__ */ | 203 | #endif /* __KERNEL__ */ |
195 | 204 | ||
196 | #endif /* _ASM_THREAD_INFO_H */ | 205 | #endif /* _ASM_THREAD_INFO_H */ |
diff --git a/include/asm-x86/thread_info_64.h b/include/asm-x86/thread_info_64.h index ed664e874dec..cb69f70abba1 100644 --- a/include/asm-x86/thread_info_64.h +++ b/include/asm-x86/thread_info_64.h | |||
@@ -109,7 +109,6 @@ static inline struct thread_info *stack_thread_info(void) | |||
109 | #define TIF_IRET 5 /* force IRET */ | 109 | #define TIF_IRET 5 /* force IRET */ |
110 | #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ | 110 | #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ |
111 | #define TIF_SECCOMP 8 /* secure computing */ | 111 | #define TIF_SECCOMP 8 /* secure computing */ |
112 | #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ | ||
113 | #define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */ | 112 | #define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */ |
114 | #define TIF_HRTICK_RESCHED 11 /* reprogram hrtick timer */ | 113 | #define TIF_HRTICK_RESCHED 11 /* reprogram hrtick timer */ |
115 | /* 16 free */ | 114 | /* 16 free */ |
@@ -133,7 +132,6 @@ static inline struct thread_info *stack_thread_info(void) | |||
133 | #define _TIF_IRET (1 << TIF_IRET) | 132 | #define _TIF_IRET (1 << TIF_IRET) |
134 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) | 133 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) |
135 | #define _TIF_SECCOMP (1 << TIF_SECCOMP) | 134 | #define _TIF_SECCOMP (1 << TIF_SECCOMP) |
136 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) | ||
137 | #define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY) | 135 | #define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY) |
138 | #define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED) | 136 | #define _TIF_HRTICK_RESCHED (1 << TIF_HRTICK_RESCHED) |
139 | #define _TIF_IA32 (1 << TIF_IA32) | 137 | #define _TIF_IA32 (1 << TIF_IA32) |
@@ -178,9 +176,20 @@ static inline struct thread_info *stack_thread_info(void) | |||
178 | #define TS_COMPAT 0x0002 /* 32bit syscall active */ | 176 | #define TS_COMPAT 0x0002 /* 32bit syscall active */ |
179 | #define TS_POLLING 0x0004 /* true if in idle loop | 177 | #define TS_POLLING 0x0004 /* true if in idle loop |
180 | and not sleeping */ | 178 | and not sleeping */ |
179 | #define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal() */ | ||
181 | 180 | ||
182 | #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) | 181 | #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) |
183 | 182 | ||
183 | #ifndef __ASSEMBLY__ | ||
184 | #define HAVE_SET_RESTORE_SIGMASK 1 | ||
185 | static inline void set_restore_sigmask(void) | ||
186 | { | ||
187 | struct thread_info *ti = current_thread_info(); | ||
188 | ti->status |= TS_RESTORE_SIGMASK; | ||
189 | set_bit(TIF_SIGPENDING, &ti->flags); | ||
190 | } | ||
191 | #endif /* !__ASSEMBLY__ */ | ||
192 | |||
184 | #endif /* __KERNEL__ */ | 193 | #endif /* __KERNEL__ */ |
185 | 194 | ||
186 | #endif /* _ASM_THREAD_INFO_H */ | 195 | #endif /* _ASM_THREAD_INFO_H */ |