utrace_reset(action) changes *action only when there are no attached
engines, utrace_stop() can't rely on "stop != UTRACE_STOP" check.

Change utrace_stop() to call utrace_reset(action => NULL) and recheck
->utrace_flags.

action => NULL may cause the unnecessary utrace_wakeup(current), but
this case is unlikely and harmless.

Also, move "unlikely()" from the first check to the second, afaics this
matches the reality.

Well, as I said I believe the comment is misleading, but I can't suggest
something better.

Signed-off-by: Oleg Nesterov <o...@redhat.com>

--- __UTRACE/kernel/utrace.c~1_STOP_DETACH_FIX  2009-08-26 11:42:17.000000000 
+0200
+++ __UTRACE/kernel/utrace.c    2009-08-26 12:30:38.000000000 +0200
@@ -811,7 +811,7 @@ static void utrace_stop(struct task_stru
 relock:
        spin_lock(&utrace->lock);
 
-       if (unlikely(!(task->utrace_flags & ENGINE_STOP))) {
+       if (!(task->utrace_flags & ENGINE_STOP)) {
                /*
                 * UTRACE_DETACH was used in some utrace_control()
                 * call since the last time we ran utrace_reset().
@@ -820,9 +820,8 @@ relock:
                 * would be nobody to resume us.  So we must check over
                 * still-attached engines and recompute the flags.
                 */
-               enum utrace_resume_action stop = UTRACE_STOP;
-               utrace_reset(task, utrace, &stop);
-               if (stop != UTRACE_STOP)
+               utrace_reset(task, utrace, NULL);
+               if (unlikely(!(task->utrace_flags & ENGINE_STOP)))
                        return;
                goto relock;
        }

Reply via email to