Merge master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6
[pandora-kernel.git] / kernel / exit.c
index 7be283d..5b0fb9f 100644 (file)
@@ -72,6 +72,11 @@ repeat:
        BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
        __exit_signal(p);
        __exit_sighand(p);
+       /*
+        * Note that the fastpath in sys_times depends on __exit_signal having
+        * updated the counters before a task is removed from the tasklist of
+        * the process by __unhash_process.
+        */
        __unhash_process(p);
 
        /*
@@ -779,6 +784,8 @@ fastcall NORET_TYPE void do_exit(long code)
 
        profile_task_exit(tsk);
 
+       WARN_ON(atomic_read(&tsk->fs_excl));
+
        if (unlikely(in_interrupt()))
                panic("Aiee, killing interrupt handler!");
        if (unlikely(!tsk->pid))
@@ -793,6 +800,17 @@ fastcall NORET_TYPE void do_exit(long code)
                ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
        }
 
+       /*
+        * We're taking recursive faults here in do_exit. Safest is to just
+        * leave this task alone and wait for reboot.
+        */
+       if (unlikely(tsk->flags & PF_EXITING)) {
+               printk(KERN_ALERT
+                       "Fixing recursive fault but reboot is needed!\n");
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule();
+       }
+
        tsk->flags |= PF_EXITING;
 
        /*
@@ -846,6 +864,8 @@ fastcall NORET_TYPE void do_exit(long code)
        for (;;) ;
 }
 
+EXPORT_SYMBOL_GPL(do_exit);
+
 NORET_TYPE void complete_and_exit(struct completion *comp, long code)
 {
        if (comp)