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 /arch/x86 | |
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>
Diffstat (limited to 'arch/x86')
-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 |
3 files changed, 18 insertions, 17 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) |