]> err.no Git - linux-2.6/blobdiff - kernel/exit.c
[ALSA] hda-intel - correct a bug in detection of rate supported
[linux-2.6] / kernel / exit.c
index 419d9d3c4c488b4336fe8203f09464afe73b7d30..5b0fb9f09f212d05642dd343be2692a2b0a039b7 100644 (file)
@@ -39,6 +39,8 @@ extern struct task_struct *child_reaper;
 
 int getrusage(struct task_struct *, int, struct rusage __user *);
 
+static void exit_mm(struct task_struct * tsk);
+
 static void __unhash_process(struct task_struct *p)
 {
        nr_threads--;
@@ -70,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);
 
        /*
@@ -474,7 +481,7 @@ EXPORT_SYMBOL_GPL(exit_fs);
  * Turn us into a lazy TLB process if we
  * aren't already..
  */
-void exit_mm(struct task_struct * tsk)
+static void exit_mm(struct task_struct * tsk)
 {
        struct mm_struct *mm = tsk->mm;
 
@@ -777,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))
@@ -791,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;
 
        /*
@@ -844,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)