summaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index bc0ec674d3f..1a9787ac617 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -34,6 +34,7 @@
#include <linux/mutex.h>
#include <linux/futex.h>
#include <linux/compat.h>
+#include <linux/pipe_fs_i.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -127,6 +128,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;
@@ -168,7 +174,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))
@@ -936,6 +942,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);