copy_process(): remove the unneeded clear_tsk_thread_flag(TIF_SIGPENDING)
[cascardo/linux.git] / kernel / exit.c
index 73affd3..94a9992 100644 (file)
@@ -48,7 +48,8 @@
 #include <linux/tracehook.h>
 #include <linux/fs_struct.h>
 #include <linux/init_task.h>
-#include <trace/sched.h>
+#include <linux/perf_counter.h>
+#include <trace/events/sched.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/mmu_context.h>
 #include "cred-internals.h"
 
-DEFINE_TRACE(sched_process_free);
-DEFINE_TRACE(sched_process_exit);
-DEFINE_TRACE(sched_process_wait);
-
 static void exit_mm(struct task_struct * tsk);
 
 static void __unhash_process(struct task_struct *p)
@@ -159,7 +156,7 @@ static void delayed_put_task_struct(struct rcu_head *rhp)
        struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
 
 #ifdef CONFIG_PERF_COUNTERS
-       WARN_ON_ONCE(!list_empty(&tsk->perf_counter_ctx.counter_list));
+       WARN_ON_ONCE(tsk->perf_counter_ctxp);
 #endif
        trace_sched_process_free(tsk);
        put_task_struct(tsk);
@@ -178,12 +175,6 @@ repeat:
 
        proc_flush_task(p);
 
-       /*
-        * Flush inherited counters to the parent - before the parent
-        * gets woken up by child-exit notifications.
-        */
-       perf_counter_exit_task(p);
-
        write_lock_irq(&tasklist_lock);
        tracehook_finish_release_task(p);
        __exit_signal(p);
@@ -384,9 +375,8 @@ static void set_special_pids(struct pid *pid)
 }
 
 /*
- * Let kernel threads use this to say that they
- * allow a certain signal (since daemonize() will
- * have disabled all of them by default).
+ * Let kernel threads use this to say that they allow a certain signal.
+ * Must not be used if kthread was cloned with CLONE_SIGHAND.
  */
 int allow_signal(int sig)
 {
@@ -394,14 +384,14 @@ int allow_signal(int sig)
                return -EINVAL;
 
        spin_lock_irq(&current->sighand->siglock);
+       /* This is only needed for daemonize()'ed kthreads */
        sigdelset(&current->blocked, sig);
-       if (!current->mm) {
-               /* Kernel threads handle their own signals.
-                  Let the signal code know it'll be handled, so
-                  that they don't get converted to SIGKILL or
-                  just silently dropped */
-               current->sighand->action[(sig)-1].sa.sa_handler = (void __user *)2;
-       }
+       /*
+        * Kernel threads handle their own signals. Let the signal code
+        * know it'll be handled, so that they don't get converted to
+        * SIGKILL or just silently dropped.
+        */
+       current->sighand->action[(sig)-1].sa.sa_handler = (void __user *)2;
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
        return 0;
@@ -600,7 +590,7 @@ retry:
        /*
         * Search in the siblings
         */
-       list_for_each_entry(c, &p->parent->children, sibling) {
+       list_for_each_entry(c, &p->real_parent->children, sibling) {
                if (c->mm == mm)
                        goto assign_new_owner;
        }
@@ -767,7 +757,7 @@ static void reparent_thread(struct task_struct *father, struct task_struct *p,
        p->exit_signal = SIGCHLD;
 
        /* If it has exited notify the new parent about this child's death. */
-       if (!p->ptrace &&
+       if (!task_ptrace(p) &&
            p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
                do_notify_parent(p, p->exit_signal);
                if (task_detached(p)) {
@@ -792,7 +782,7 @@ static void forget_original_parent(struct task_struct *father)
        list_for_each_entry_safe(p, n, &father->children, sibling) {
                p->real_parent = reaper;
                if (p->parent == father) {
-                       BUG_ON(p->ptrace);
+                       BUG_ON(task_ptrace(p));
                        p->parent = p->real_parent;
                }
                reparent_thread(father, p, &dead_children);
@@ -985,6 +975,13 @@ NORET_TYPE void do_exit(long code)
                module_put(tsk->binfmt->module);
 
        proc_exit_connector(tsk);
+
+       /*
+        * Flush inherited counters to the parent - before the parent
+        * gets woken up by child-exit notifications.
+        */
+       perf_counter_exit_task(tsk);
+
        exit_notify(tsk, group_dead);
 #ifdef CONFIG_NUMA
        mpol_put(tsk->mempolicy);
@@ -1194,7 +1191,6 @@ static int wait_task_zombie(struct task_struct *p, int options,
        if (likely(!traced)) {
                struct signal_struct *psig;
                struct signal_struct *sig;
-               struct task_cputime cputime;
 
                /*
                 * The resource counters for the group leader are in its
@@ -1207,26 +1203,23 @@ static int wait_task_zombie(struct task_struct *p, int options,
                 * p->signal fields, because they are only touched by
                 * __exit_signal, which runs with tasklist_lock
                 * write-locked anyway, and so is excluded here.  We do
-                * need to protect the access to p->parent->signal fields,
+                * need to protect the access to parent->signal fields,
                 * as other threads in the parent group can be right
                 * here reaping other children at the same time.
-                *
-                * We use thread_group_cputime() to get times for the thread
-                * group, which consolidates times for all threads in the
-                * group including the group leader.
                 */
-               thread_group_cputime(p, &cputime);
-               spin_lock_irq(&p->parent->sighand->siglock);
-               psig = p->parent->signal;
+               spin_lock_irq(&p->real_parent->sighand->siglock);
+               psig = p->real_parent->signal;
                sig = p->signal;
                psig->cutime =
                        cputime_add(psig->cutime,
-                       cputime_add(cputime.utime,
-                                   sig->cutime));
+                       cputime_add(p->utime,
+                       cputime_add(sig->utime,
+                                   sig->cutime)));
                psig->cstime =
                        cputime_add(psig->cstime,
-                       cputime_add(cputime.stime,
-                                   sig->cstime));
+                       cputime_add(p->stime,
+                       cputime_add(sig->stime,
+                                   sig->cstime)));
                psig->cgtime =
                        cputime_add(psig->cgtime,
                        cputime_add(p->gtime,
@@ -1248,7 +1241,7 @@ static int wait_task_zombie(struct task_struct *p, int options,
                        sig->oublock + sig->coublock;
                task_io_accounting_add(&psig->ioac, &p->ioac);
                task_io_accounting_add(&psig->ioac, &sig->ioac);
-               spin_unlock_irq(&p->parent->sighand->siglock);
+               spin_unlock_irq(&p->real_parent->sighand->siglock);
        }
 
        /*
@@ -1257,12 +1250,6 @@ static int wait_task_zombie(struct task_struct *p, int options,
         */
        read_unlock(&tasklist_lock);
 
-       /*
-        * Flush inherited counters to the parent - before the parent
-        * gets woken up by child-exit notifications.
-        */
-       perf_counter_exit_task(p);
-
        retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
        status = (p->signal->flags & SIGNAL_GROUP_EXIT)
                ? p->signal->group_exit_code : p->exit_code;
@@ -1488,9 +1475,10 @@ static int wait_consider_task(struct task_struct *parent, int ptrace,
                 */
                if (*notask_error)
                        *notask_error = ret;
+               return 0;
        }
 
-       if (likely(!ptrace) && unlikely(p->ptrace)) {
+       if (likely(!ptrace) && unlikely(task_ptrace(p))) {
                /*
                 * This child is hidden by ptrace.
                 * We aren't allowed to see it now, but eventually we will.