ALSA: hda - Fix MacBookPro 3,1/4,1 quirk with ALC889A
[pandora-kernel.git] / kernel / exit.c
index 29622e4..628d41f 100644 (file)
@@ -1082,8 +1082,8 @@ SYSCALL_DEFINE1(exit_group, int, error_code)
 
 struct wait_opts {
        enum pid_type           wo_type;
-       struct pid              *wo_pid;
        int                     wo_flags;
+       struct pid              *wo_pid;
 
        struct siginfo __user   *wo_info;
        int __user              *wo_stat;
@@ -1197,8 +1197,11 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
        }
 
        traced = ptrace_reparented(p);
-
-       if (likely(!traced)) {
+       /*
+        * It can be ptraced but not reparented, check
+        * !task_detached() to filter out sub-threads.
+        */
+       if (likely(!traced) && likely(!task_detached(p))) {
                struct signal_struct *psig;
                struct signal_struct *sig;
 
@@ -1576,35 +1579,29 @@ repeat:
         * might later match our criteria, even if we are not able to reap
         * it yet.
         */
-       retval = wo->notask_error = -ECHILD;
+       wo->notask_error = -ECHILD;
        if ((wo->wo_type < PIDTYPE_MAX) &&
           (!wo->wo_pid || hlist_empty(&wo->wo_pid->tasks[wo->wo_type])))
-               goto end;
+               goto notask;
 
-       current->state = TASK_INTERRUPTIBLE;
+       set_current_state(TASK_INTERRUPTIBLE);
        read_lock(&tasklist_lock);
        tsk = current;
        do {
-               int tsk_result = do_wait_thread(wo, tsk);
-
-               if (!tsk_result)
-                       tsk_result = ptrace_do_wait(wo, tsk);
+               retval = do_wait_thread(wo, tsk);
+               if (retval)
+                       goto end;
 
-               if (tsk_result) {
-                       /*
-                        * tasklist_lock is unlocked and we have a final result.
-                        */
-                       retval = tsk_result;
+               retval = ptrace_do_wait(wo, tsk);
+               if (retval)
                        goto end;
-               }
 
                if (wo->wo_flags & __WNOTHREAD)
                        break;
-               tsk = next_thread(tsk);
-               BUG_ON(tsk->signal != current->signal);
-       } while (tsk != current);
+       } while_each_thread(current, tsk);
        read_unlock(&tasklist_lock);
 
+notask:
        retval = wo->notask_error;
        if (!retval && !(wo->wo_flags & WNOHANG)) {
                retval = -ERESTARTSYS;
@@ -1614,7 +1611,7 @@ repeat:
                }
        }
 end:
-       current->state = TASK_RUNNING;
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(&current->signal->wait_chldexit,&wait);
        if (wo->wo_info) {
                struct siginfo __user *infop = wo->wo_info;