]> err.no Git - linux-2.6/blobdiff - kernel/exit.c
cfi-cmdset-0001: always update the chip status
[linux-2.6] / kernel / exit.c
index 6b2e4cf3e140e7eef27635fc4fb1b8f1f224c9fe..e95b932822109e6bd517eee9a67876fedc91b426 100644 (file)
@@ -34,6 +34,8 @@
 #include <linux/mutex.h>
 #include <linux/futex.h>
 #include <linux/compat.h>
+#include <linux/pipe_fs_i.h>
+#include <linux/audit.h> /* for audit_free() */
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -51,15 +53,14 @@ static void __unhash_process(struct task_struct *p)
 {
        nr_threads--;
        detach_pid(p, PIDTYPE_PID);
-       detach_pid(p, PIDTYPE_TGID);
        if (thread_group_leader(p)) {
                detach_pid(p, PIDTYPE_PGID);
                detach_pid(p, PIDTYPE_SID);
 
-               list_del_init(&p->tasks);
+               list_del_rcu(&p->tasks);
                __get_cpu_var(process_counts)--;
        }
-
+       list_del_rcu(&p->thread_group);
        remove_parent(p);
 }
 
@@ -112,11 +113,14 @@ static void __exit_signal(struct task_struct *tsk)
                sig = NULL; /* Marker for below. */
        }
 
+       __unhash_process(tsk);
+
        tsk->signal = NULL;
-       cleanup_sighand(tsk);
+       tsk->sighand = NULL;
        spin_unlock(&sighand->siglock);
        rcu_read_unlock();
 
+       __cleanup_sighand(sighand);
        clear_tsk_thread_flag(tsk,TIF_SIGPENDING);
        flush_sigqueue(&tsk->pending);
        if (sig) {
@@ -125,6 +129,11 @@ static void __exit_signal(struct task_struct *tsk)
        }
 }
 
+static void delayed_put_task_struct(struct rcu_head *rhp)
+{
+       put_task_struct(container_of(rhp, struct task_struct, rcu));
+}
+
 void release_task(struct task_struct * p)
 {
        int zap_leader;
@@ -140,8 +149,6 @@ repeat:
        BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
        __exit_signal(p);
 
-       __unhash_process(p);
-
        /*
         * If we are the last non-leader member of the thread
         * group, and the leader is zombie, then notify the
@@ -168,7 +175,7 @@ repeat:
        spin_unlock(&p->proc_lock);
        proc_pid_flush(proc_dentry);
        release_thread(p);
-       put_task_struct(p);
+       call_rcu(&p->rcu, delayed_put_task_struct);
 
        p = leader;
        if (unlikely(zap_leader))
@@ -904,6 +911,8 @@ fastcall NORET_TYPE void do_exit(long code)
        if (unlikely(tsk->compat_robust_list))
                compat_exit_robust_list(tsk);
 #endif
+       if (unlikely(tsk->audit_context))
+               audit_free(tsk);
        exit_mm(tsk);
 
        exit_sem(tsk);
@@ -936,6 +945,9 @@ fastcall NORET_TYPE void do_exit(long code)
        if (tsk->io_context)
                exit_io_context();
 
+       if (tsk->splice_pipe)
+               __free_pipe_info(tsk->splice_pipe);
+
        /* PF_DEAD causes final put_task_struct after we schedule. */
        preempt_disable();
        BUG_ON(tsk->flags & PF_DEAD);
@@ -964,13 +976,6 @@ asmlinkage long sys_exit(int error_code)
        do_exit((error_code&0xff)<<8);
 }
 
-task_t fastcall *next_thread(const task_t *p)
-{
-       return pid_task(p->pids[PIDTYPE_TGID].pid_list.next, PIDTYPE_TGID);
-}
-
-EXPORT_SYMBOL(next_thread);
-
 /*
  * Take down every thread in the group.  This is called by fatal signals
  * as well as by sys_exit_group (below).
@@ -985,7 +990,6 @@ do_group_exit(int exit_code)
        else if (!thread_group_empty(current)) {
                struct signal_struct *const sig = current->signal;
                struct sighand_struct *const sighand = current->sighand;
-               read_lock(&tasklist_lock);
                spin_lock_irq(&sighand->siglock);
                if (sig->flags & SIGNAL_GROUP_EXIT)
                        /* Another thread got here before we took the lock.  */
@@ -995,7 +999,6 @@ do_group_exit(int exit_code)
                        zap_other_threads(current);
                }
                spin_unlock_irq(&sighand->siglock);
-               read_unlock(&tasklist_lock);
        }
 
        do_exit(exit_code);