ARM: sunxi_defconfig: enable CONFIG_REGULATOR
[cascardo/linux.git] / kernel / exit.c
index 32c58f7..5d30019 100644 (file)
@@ -115,32 +115,33 @@ static void __exit_signal(struct task_struct *tsk)
 
                if (tsk == sig->curr_target)
                        sig->curr_target = next_thread(tsk);
-               /*
-                * Accumulate here the counters for all threads but the
-                * group leader as they die, so they can be added into
-                * the process-wide totals when those are taken.
-                * The group leader stays around as a zombie as long
-                * as there are other threads.  When it gets reaped,
-                * the exit.c code will add its counts into these totals.
-                * We won't ever get here for the group leader, since it
-                * will have been the last reference on the signal_struct.
-                */
-               task_cputime(tsk, &utime, &stime);
-               sig->utime += utime;
-               sig->stime += stime;
-               sig->gtime += task_gtime(tsk);
-               sig->min_flt += tsk->min_flt;
-               sig->maj_flt += tsk->maj_flt;
-               sig->nvcsw += tsk->nvcsw;
-               sig->nivcsw += tsk->nivcsw;
-               sig->inblock += task_io_get_inblock(tsk);
-               sig->oublock += task_io_get_oublock(tsk);
-               task_io_accounting_add(&sig->ioac, &tsk->ioac);
-               sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
        }
 
+       /*
+        * Accumulate here the counters for all threads but the group leader
+        * as they die, so they can be added into the process-wide totals
+        * when those are taken.  The group leader stays around as a zombie as
+        * long as there are other threads.  When it gets reaped, the exit.c
+        * code will add its counts into these totals.  We won't ever get here
+        * for the group leader, since it will have been the last reference on
+        * the signal_struct.
+        */
+       task_cputime(tsk, &utime, &stime);
+       write_seqlock(&sig->stats_lock);
+       sig->utime += utime;
+       sig->stime += stime;
+       sig->gtime += task_gtime(tsk);
+       sig->min_flt += tsk->min_flt;
+       sig->maj_flt += tsk->maj_flt;
+       sig->nvcsw += tsk->nvcsw;
+       sig->nivcsw += tsk->nivcsw;
+       sig->inblock += task_io_get_inblock(tsk);
+       sig->oublock += task_io_get_oublock(tsk);
+       task_io_accounting_add(&sig->ioac, &tsk->ioac);
+       sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
        sig->nr_threads--;
        __unhash_process(tsk, group_dead);
+       write_sequnlock(&sig->stats_lock);
 
        /*
         * Do this under ->siglock, we can race with another thread
@@ -667,6 +668,7 @@ void do_exit(long code)
 {
        struct task_struct *tsk = current;
        int group_dead;
+       TASKS_RCU(int tasks_rcu_i);
 
        profile_task_exit(tsk);
 
@@ -775,6 +777,7 @@ void do_exit(long code)
         */
        flush_ptrace_hw_breakpoint(tsk);
 
+       TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
        exit_notify(tsk, group_dead);
        proc_exit_connector(tsk);
 #ifdef CONFIG_NUMA
@@ -814,6 +817,7 @@ void do_exit(long code)
        if (tsk->nr_dirtied)
                __this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied);
        exit_rcu();
+       TASKS_RCU(__srcu_read_unlock(&tasks_rcu_exit_srcu, tasks_rcu_i));
 
        /*
         * The setting of TASK_RUNNING by try_to_wake_up() may be delayed
@@ -1043,6 +1047,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
                spin_lock_irq(&p->real_parent->sighand->siglock);
                psig = p->real_parent->signal;
                sig = p->signal;
+               write_seqlock(&psig->stats_lock);
                psig->cutime += tgutime + sig->cutime;
                psig->cstime += tgstime + sig->cstime;
                psig->cgtime += task_gtime(p) + sig->gtime + sig->cgtime;
@@ -1065,6 +1070,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
                        psig->cmaxrss = maxrss;
                task_io_accounting_add(&psig->ioac, &p->ioac);
                task_io_accounting_add(&psig->ioac, &sig->ioac);
+               write_sequnlock(&psig->stats_lock);
                spin_unlock_irq(&p->real_parent->sighand->siglock);
        }