diff options
-rw-r--r-- | include/linux/sched.h | 6 | ||||
-rw-r--r-- | kernel/signal.c | 14 |
2 files changed, 7 insertions, 13 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 456d80ed3b78..8cef82d4cf77 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -652,9 +652,8 @@ struct signal_struct { | |||
652 | * Bits in flags field of signal_struct. | 652 | * Bits in flags field of signal_struct. |
653 | */ | 653 | */ |
654 | #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ | 654 | #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ |
655 | #define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */ | 655 | #define SIGNAL_STOP_CONTINUED 0x00000002 /* SIGCONT since WCONTINUED reap */ |
656 | #define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ | 656 | #define SIGNAL_GROUP_EXIT 0x00000004 /* group exit in progress */ |
657 | #define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ | ||
658 | /* | 657 | /* |
659 | * Pending notifications to parent. | 658 | * Pending notifications to parent. |
660 | */ | 659 | */ |
@@ -1779,6 +1778,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * | |||
1779 | #define GROUP_STOP_PENDING (1 << 16) /* task should stop for group stop */ | 1778 | #define GROUP_STOP_PENDING (1 << 16) /* task should stop for group stop */ |
1780 | #define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ | 1779 | #define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ |
1781 | #define GROUP_STOP_TRAPPING (1 << 18) /* switching from STOPPED to TRACED */ | 1780 | #define GROUP_STOP_TRAPPING (1 << 18) /* switching from STOPPED to TRACED */ |
1781 | #define GROUP_STOP_DEQUEUED (1 << 19) /* stop signal dequeued */ | ||
1782 | 1782 | ||
1783 | extern void task_clear_group_stop_pending(struct task_struct *task); | 1783 | extern void task_clear_group_stop_pending(struct task_struct *task); |
1784 | 1784 | ||
diff --git a/kernel/signal.c b/kernel/signal.c index e9abc69dc0d8..4f7312b49b2d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -254,7 +254,8 @@ static void task_clear_group_stop_trapping(struct task_struct *task) | |||
254 | */ | 254 | */ |
255 | void task_clear_group_stop_pending(struct task_struct *task) | 255 | void task_clear_group_stop_pending(struct task_struct *task) |
256 | { | 256 | { |
257 | task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME); | 257 | task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME | |
258 | GROUP_STOP_DEQUEUED); | ||
258 | } | 259 | } |
259 | 260 | ||
260 | /** | 261 | /** |
@@ -602,7 +603,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
602 | * is to alert stop-signal processing code when another | 603 | * is to alert stop-signal processing code when another |
603 | * processor has come along and cleared the flag. | 604 | * processor has come along and cleared the flag. |
604 | */ | 605 | */ |
605 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; | 606 | current->group_stop |= GROUP_STOP_DEQUEUED; |
606 | } | 607 | } |
607 | if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { | 608 | if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { |
608 | /* | 609 | /* |
@@ -821,13 +822,6 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) | |||
821 | signal->flags = why | SIGNAL_STOP_CONTINUED; | 822 | signal->flags = why | SIGNAL_STOP_CONTINUED; |
822 | signal->group_stop_count = 0; | 823 | signal->group_stop_count = 0; |
823 | signal->group_exit_code = 0; | 824 | signal->group_exit_code = 0; |
824 | } else { | ||
825 | /* | ||
826 | * We are not stopped, but there could be a stop | ||
827 | * signal in the middle of being processed after | ||
828 | * being removed from the queue. Clear that too. | ||
829 | */ | ||
830 | signal->flags &= ~SIGNAL_STOP_DEQUEUED; | ||
831 | } | 825 | } |
832 | } | 826 | } |
833 | 827 | ||
@@ -1855,7 +1849,7 @@ static int do_signal_stop(int signr) | |||
1855 | /* signr will be recorded in task->group_stop for retries */ | 1849 | /* signr will be recorded in task->group_stop for retries */ |
1856 | WARN_ON_ONCE(signr & ~GROUP_STOP_SIGMASK); | 1850 | WARN_ON_ONCE(signr & ~GROUP_STOP_SIGMASK); |
1857 | 1851 | ||
1858 | if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || | 1852 | if (!likely(current->group_stop & GROUP_STOP_DEQUEUED) || |
1859 | unlikely(signal_group_exit(sig))) | 1853 | unlikely(signal_group_exit(sig))) |
1860 | return 0; | 1854 | return 0; |
1861 | /* | 1855 | /* |