arm: tegra: cardhu/enterprise: Remove pinmux conflicts
[linux-2.6.git] / kernel / exit.c
index 2b1ba80..4b4042f 100644 (file)
@@ -51,6 +51,7 @@
 #include <trace/events/sched.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/oom.h>
+#include <linux/writeback.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -85,7 +86,6 @@ static void __exit_signal(struct task_struct *tsk)
        struct tty_struct *uninitialized_var(tty);
 
        sighand = rcu_dereference_check(tsk->sighand,
-                                       rcu_read_lock_held() ||
                                        lockdep_tasklist_lock_is_held());
        spin_lock(&sighand->siglock);
 
@@ -122,9 +122,9 @@ static void __exit_signal(struct task_struct *tsk)
                 * We won't ever get here for the group leader, since it
                 * will have been the last reference on the signal_struct.
                 */
-               sig->utime = cputime_add(sig->utime, tsk->utime);
-               sig->stime = cputime_add(sig->stime, tsk->stime);
-               sig->gtime = cputime_add(sig->gtime, tsk->gtime);
+               sig->utime += tsk->utime;
+               sig->stime += tsk->stime;
+               sig->gtime += tsk->gtime;
                sig->min_flt += tsk->min_flt;
                sig->maj_flt += tsk->maj_flt;
                sig->nvcsw += tsk->nvcsw;
@@ -189,7 +189,6 @@ repeat:
        zap_leader = 0;
        leader = p->group_leader;
        if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) {
-               BUG_ON(task_detached(leader));
                /*
                 * If we were the last child thread and the leader has
                 * exited already, and the leader's parent ignores SIGCHLD,
@@ -267,18 +266,16 @@ int is_current_pgrp_orphaned(void)
        return retval;
 }
 
-static int has_stopped_jobs(struct pid *pgrp)
+static bool has_stopped_jobs(struct pid *pgrp)
 {
-       int retval = 0;
        struct task_struct *p;
 
        do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
-               if (!task_is_stopped(p))
-                       continue;
-               retval = 1;
-               break;
+               if (p->signal->flags & SIGNAL_STOP_STOPPED)
+                       return true;
        } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
-       return retval;
+
+       return false;
 }
 
 /*
@@ -551,29 +548,28 @@ void exit_files(struct task_struct *tsk)
 
 #ifdef CONFIG_MM_OWNER
 /*
- * Task p is exiting and it owned mm, lets find a new owner for it
+ * A task is exiting.   If it owned this mm, find a new owner for the mm.
  */
-static inline int
-mm_need_new_owner(struct mm_struct *mm, struct task_struct *p)
-{
-       /*
-        * If there are other users of the mm and the owner (us) is exiting
-        * we need to find a new owner to take on the responsibility.
-        */
-       if (atomic_read(&mm->mm_users) <= 1)
-               return 0;
-       if (mm->owner != p)
-               return 0;
-       return 1;
-}
-
 void mm_update_next_owner(struct mm_struct *mm)
 {
        struct task_struct *c, *g, *p = current;
 
 retry:
-       if (!mm_need_new_owner(mm, p))
+       /*
+        * If the exiting or execing task is not the owner, it's
+        * someone else's problem.
+        */
+       if (mm->owner != p)
                return;
+       /*
+        * The current owner is exiting/execing and there are no other
+        * candidates.  Do not leave the mm pointing to a possibly
+        * freed task structure.
+        */
+       if (atomic_read(&mm->mm_users) <= 1) {
+               mm->owner = NULL;
+               return;
+       }
 
        read_lock(&tasklist_lock);
        /*
@@ -684,10 +680,6 @@ static void exit_mm(struct task_struct * tsk)
        tsk->mm = NULL;
        up_read(&mm->mmap_sem);
        enter_lazy_tlb(mm, current);
-       /* We don't want this task to be frozen prematurely */
-       clear_freeze_flag(tsk);
-       if (tsk->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
-               atomic_dec(&mm->oom_disable_count);
        task_unlock(tsk);
        mm_update_next_owner(mm);
        mmput(mm);
@@ -895,14 +887,13 @@ static void check_stack_usage(void)
 static inline void check_stack_usage(void) {}
 #endif
 
-NORET_TYPE void do_exit(long code)
+void do_exit(long code)
 {
        struct task_struct *tsk = current;
        int group_dead;
 
        profile_task_exit(tsk);
 
-       WARN_ON(atomic_read(&tsk->fs_excl));
        WARN_ON(blk_needs_flush_plug(tsk));
 
        if (unlikely(in_interrupt()))
@@ -973,8 +964,7 @@ NORET_TYPE void do_exit(long code)
        acct_collect(code, group_dead);
        if (group_dead)
                tty_audit_exit();
-       if (unlikely(tsk->audit_context))
-               audit_free(tsk);
+       audit_free(tsk);
 
        tsk->exit_code = code;
        taskstats_exit(tsk, group_dead);
@@ -986,6 +976,7 @@ NORET_TYPE void do_exit(long code)
        trace_sched_process_exit(tsk);
 
        exit_sem(tsk);
+       exit_shm(tsk);
        exit_files(tsk);
        exit_fs(tsk);
        check_stack_usage();
@@ -1044,9 +1035,28 @@ NORET_TYPE void do_exit(long code)
        validate_creds_for_do_exit(tsk);
 
        preempt_disable();
+       if (tsk->nr_dirtied)
+               __this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied);
        exit_rcu();
+
+       /*
+        * The setting of TASK_RUNNING by try_to_wake_up() may be delayed
+        * when the following two conditions become true.
+        *   - There is race condition of mmap_sem (It is acquired by
+        *     exit_mm()), and
+        *   - SMI occurs before setting TASK_RUNINNG.
+        *     (or hypervisor of virtual machine switches to other guest)
+        *  As a result, we may become TASK_RUNNING after becoming TASK_DEAD
+        *
+        * To avoid it, we have to wait for releasing tsk->pi_lock which
+        * is held by try_to_wake_up()
+        */
+       smp_mb();
+       raw_spin_unlock_wait(&tsk->pi_lock);
+
        /* causes final put_task_struct in finish_task_switch(). */
        tsk->state = TASK_DEAD;
+       tsk->flags |= PF_NOFREEZE;      /* tell freezer to ignore us */
        schedule();
        BUG();
        /* Avoid "noreturn function does return".  */
@@ -1056,7 +1066,7 @@ NORET_TYPE void do_exit(long code)
 
 EXPORT_SYMBOL_GPL(do_exit);
 
-NORET_TYPE void complete_and_exit(struct completion *comp, long code)
+void complete_and_exit(struct completion *comp, long code)
 {
        if (comp)
                complete(comp);
@@ -1075,7 +1085,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
  * Take down every thread in the group.  This is called by fatal signals
  * as well as by sys_exit_group (below).
  */
-NORET_TYPE void
+void
 do_group_exit(int exit_code)
 {
        struct signal_struct *sig = current->signal;
@@ -1231,9 +1241,9 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
        traced = ptrace_reparented(p);
        /*
         * It can be ptraced but not reparented, check
-        * !task_detached() to filter out sub-threads.
+        * thread_group_leader() to filter out sub-threads.
         */
-       if (likely(!traced) && likely(!task_detached(p))) {
+       if (likely(!traced) && thread_group_leader(p)) {
                struct signal_struct *psig;
                struct signal_struct *sig;
                unsigned long maxrss;
@@ -1262,19 +1272,9 @@ 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;
-               psig->cutime =
-                       cputime_add(psig->cutime,
-                       cputime_add(tgutime,
-                                   sig->cutime));
-               psig->cstime =
-                       cputime_add(psig->cstime,
-                       cputime_add(tgstime,
-                                   sig->cstime));
-               psig->cgtime =
-                       cputime_add(psig->cgtime,
-                       cputime_add(p->gtime,
-                       cputime_add(sig->gtime,
-                                   sig->cgtime)));
+               psig->cutime += tgutime + sig->cutime;
+               psig->cstime += tgstime + sig->cstime;
+               psig->cgtime += p->gtime + sig->gtime + sig->cgtime;
                psig->cmin_flt +=
                        p->min_flt + sig->min_flt + sig->cmin_flt;
                psig->cmaj_flt +=
@@ -1547,8 +1547,15 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
        }
 
        /* dead body doesn't have much to contribute */
-       if (p->exit_state == EXIT_DEAD)
+       if (unlikely(p->exit_state == EXIT_DEAD)) {
+               /*
+                * But do not ignore this task until the tracer does
+                * wait_task_zombie()->do_notify_parent().
+                */
+               if (likely(!ptrace) && unlikely(ptrace_reparented(p)))
+                       wo->notask_error = 0;
                return 0;
+       }
 
        /* slay zombie? */
        if (p->exit_state == EXIT_ZOMBIE) {
@@ -1600,8 +1607,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
                 * own children, it should create a separate process which
                 * takes the role of real parent.
                 */
-               if (likely(!ptrace) && p->ptrace &&
-                   same_thread_group(p->parent, p->real_parent))
+               if (likely(!ptrace) && p->ptrace && !ptrace_reparented(p))
                        return 0;
 
                /*