signal: make sure we don't get stopped with pending task_work
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 15 Jul 2012 10:10:52 +0000 (14:10 +0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 22 Jul 2012 19:57:54 +0000 (23:57 +0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
kernel/signal.c

index 677102789cf22d4847936782f6c6f67085421927..be4f856d52f81bab8184544b5dd6dd9b823bc21b 100644 (file)
@@ -1971,6 +1971,13 @@ static void ptrace_do_notify(int signr, int exit_code, int why)
 void ptrace_notify(int exit_code)
 {
        BUG_ON((exit_code & (0x7f | ~0xffff)) != SIGTRAP);
+       if (unlikely(current->task_works)) {
+               if (test_and_clear_ti_thread_flag(current_thread_info(),
+                                                  TIF_NOTIFY_RESUME)) {
+                       smp_mb__after_clear_bit();
+                       task_work_run();
+               }
+       }
 
        spin_lock_irq(&current->sighand->siglock);
        ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED);
@@ -2191,6 +2198,14 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
        struct signal_struct *signal = current->signal;
        int signr;
 
+       if (unlikely(current->task_works)) {
+               if (test_and_clear_ti_thread_flag(current_thread_info(),
+                                                  TIF_NOTIFY_RESUME)) {
+                       smp_mb__after_clear_bit();
+                       task_work_run();
+               }
+       }
+
        if (unlikely(uprobe_deny_signal()))
                return 0;