workqueue: re-add lockdep dependencies for flushing
[linux-2.6-microblaze.git] / kernel / signal.c
index d4ccea5..9c33163 100644 (file)
@@ -1961,14 +1961,27 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
                        return;
        }
 
+       set_special_state(TASK_TRACED);
+
        /*
         * We're committing to trapping.  TRACED should be visible before
         * TRAPPING is cleared; otherwise, the tracer might fail do_wait().
         * Also, transition to TRACED and updates to ->jobctl should be
         * atomic with respect to siglock and should be done after the arch
         * hook as siglock is released and regrabbed across it.
+        *
+        *     TRACER                               TRACEE
+        *
+        *     ptrace_attach()
+        * [L]   wait_on_bit(JOBCTL_TRAPPING)   [S] set_special_state(TRACED)
+        *     do_wait()
+        *       set_current_state()                smp_wmb();
+        *       ptrace_do_wait()
+        *         wait_task_stopped()
+        *           task_stopped_code()
+        * [L]         task_is_traced()         [S] task_clear_jobctl_trapping();
         */
-       set_current_state(TASK_TRACED);
+       smp_wmb();
 
        current->last_siginfo = info;
        current->exit_code = exit_code;
@@ -2176,7 +2189,7 @@ static bool do_signal_stop(int signr)
                if (task_participate_group_stop(current))
                        notify = CLD_STOPPED;
 
-               __set_current_state(TASK_STOPPED);
+               set_special_state(TASK_STOPPED);
                spin_unlock_irq(&current->sighand->siglock);
 
                /*