aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c31
1 files changed, 8 insertions, 23 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 144326b7af5..bfee931ee3f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -152,8 +152,7 @@ void __put_task_struct(struct task_struct *tsk)
152 WARN_ON(atomic_read(&tsk->usage)); 152 WARN_ON(atomic_read(&tsk->usage));
153 WARN_ON(tsk == current); 153 WARN_ON(tsk == current);
154 154
155 put_cred(tsk->real_cred); 155 exit_creds(tsk);
156 put_cred(tsk->cred);
157 delayacct_tsk_free(tsk); 156 delayacct_tsk_free(tsk);
158 157
159 if (!profile_handoff_task(tsk)) 158 if (!profile_handoff_task(tsk))
@@ -815,11 +814,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
815{ 814{
816 struct signal_struct *sig; 815 struct signal_struct *sig;
817 816
818 if (clone_flags & CLONE_THREAD) { 817 if (clone_flags & CLONE_THREAD)
819 atomic_inc(&current->signal->count);
820 atomic_inc(&current->signal->live);
821 return 0; 818 return 0;
822 }
823 819
824 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); 820 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
825 tsk->signal = sig; 821 tsk->signal = sig;
@@ -877,16 +873,6 @@ void __cleanup_signal(struct signal_struct *sig)
877 kmem_cache_free(signal_cachep, sig); 873 kmem_cache_free(signal_cachep, sig);
878} 874}
879 875
880static void cleanup_signal(struct task_struct *tsk)
881{
882 struct signal_struct *sig = tsk->signal;
883
884 atomic_dec(&sig->live);
885
886 if (atomic_dec_and_test(&sig->count))
887 __cleanup_signal(sig);
888}
889
890static void copy_flags(unsigned long clone_flags, struct task_struct *p) 876static void copy_flags(unsigned long clone_flags, struct task_struct *p)
891{ 877{
892 unsigned long new_flags = p->flags; 878 unsigned long new_flags = p->flags;
@@ -1021,10 +1007,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1021 copy_flags(clone_flags, p); 1007 copy_flags(clone_flags, p);
1022 INIT_LIST_HEAD(&p->children); 1008 INIT_LIST_HEAD(&p->children);
1023 INIT_LIST_HEAD(&p->sibling); 1009 INIT_LIST_HEAD(&p->sibling);
1024#ifdef CONFIG_PREEMPT_RCU 1010 rcu_copy_process(p);
1025 p->rcu_read_lock_nesting = 0;
1026 p->rcu_flipctr_idx = 0;
1027#endif /* #ifdef CONFIG_PREEMPT_RCU */
1028 p->vfork_done = NULL; 1011 p->vfork_done = NULL;
1029 spin_lock_init(&p->alloc_lock); 1012 spin_lock_init(&p->alloc_lock);
1030 1013
@@ -1239,6 +1222,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1239 } 1222 }
1240 1223
1241 if (clone_flags & CLONE_THREAD) { 1224 if (clone_flags & CLONE_THREAD) {
1225 atomic_inc(&current->signal->count);
1226 atomic_inc(&current->signal->live);
1242 p->group_leader = current->group_leader; 1227 p->group_leader = current->group_leader;
1243 list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); 1228 list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
1244 } 1229 }
@@ -1282,7 +1267,8 @@ bad_fork_cleanup_mm:
1282 if (p->mm) 1267 if (p->mm)
1283 mmput(p->mm); 1268 mmput(p->mm);
1284bad_fork_cleanup_signal: 1269bad_fork_cleanup_signal:
1285 cleanup_signal(p); 1270 if (!(clone_flags & CLONE_THREAD))
1271 __cleanup_signal(p->signal);
1286bad_fork_cleanup_sighand: 1272bad_fork_cleanup_sighand:
1287 __cleanup_sighand(p->sighand); 1273 __cleanup_sighand(p->sighand);
1288bad_fork_cleanup_fs: 1274bad_fork_cleanup_fs:
@@ -1307,8 +1293,7 @@ bad_fork_cleanup_put_domain:
1307 module_put(task_thread_info(p)->exec_domain->module); 1293 module_put(task_thread_info(p)->exec_domain->module);
1308bad_fork_cleanup_count: 1294bad_fork_cleanup_count:
1309 atomic_dec(&p->cred->user->processes); 1295 atomic_dec(&p->cred->user->processes);
1310 put_cred(p->real_cred); 1296 exit_creds(p);
1311 put_cred(p->cred);
1312bad_fork_free: 1297bad_fork_free:
1313 free_task(p); 1298 free_task(p);
1314fork_out: 1299fork_out: