aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 8e88b374cee9..ccdfbb16c86d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -108,8 +108,10 @@ void free_task(struct task_struct *tsk)
108} 108}
109EXPORT_SYMBOL(free_task); 109EXPORT_SYMBOL(free_task);
110 110
111void __put_task_struct(struct task_struct *tsk) 111void __put_task_struct_cb(struct rcu_head *rhp)
112{ 112{
113 struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
114
113 WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE))); 115 WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
114 WARN_ON(atomic_read(&tsk->usage)); 116 WARN_ON(atomic_read(&tsk->usage));
115 WARN_ON(tsk == current); 117 WARN_ON(tsk == current);
@@ -1060,6 +1062,12 @@ static task_t *copy_process(unsigned long clone_flags,
1060 p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL; 1062 p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
1061 1063
1062 /* 1064 /*
1065 * sigaltstack should be cleared when sharing the same VM
1066 */
1067 if ((clone_flags & (CLONE_VM|CLONE_VFORK)) == CLONE_VM)
1068 p->sas_ss_sp = p->sas_ss_size = 0;
1069
1070 /*
1063 * Syscall tracing should be turned off in the child regardless 1071 * Syscall tracing should be turned off in the child regardless
1064 * of CLONE_PTRACE. 1072 * of CLONE_PTRACE.
1065 */ 1073 */
@@ -1123,8 +1131,8 @@ static task_t *copy_process(unsigned long clone_flags,
1123 p->real_parent = current; 1131 p->real_parent = current;
1124 p->parent = p->real_parent; 1132 p->parent = p->real_parent;
1125 1133
1134 spin_lock(&current->sighand->siglock);
1126 if (clone_flags & CLONE_THREAD) { 1135 if (clone_flags & CLONE_THREAD) {
1127 spin_lock(&current->sighand->siglock);
1128 /* 1136 /*
1129 * Important: if an exit-all has been started then 1137 * Important: if an exit-all has been started then
1130 * do not create this new thread - the whole thread 1138 * do not create this new thread - the whole thread
@@ -1162,8 +1170,6 @@ static task_t *copy_process(unsigned long clone_flags,
1162 */ 1170 */
1163 p->it_prof_expires = jiffies_to_cputime(1); 1171 p->it_prof_expires = jiffies_to_cputime(1);
1164 } 1172 }
1165
1166 spin_unlock(&current->sighand->siglock);
1167 } 1173 }
1168 1174
1169 /* 1175 /*
@@ -1175,8 +1181,6 @@ static task_t *copy_process(unsigned long clone_flags,
1175 if (unlikely(p->ptrace & PT_PTRACED)) 1181 if (unlikely(p->ptrace & PT_PTRACED))
1176 __ptrace_link(p, current->parent); 1182 __ptrace_link(p, current->parent);
1177 1183
1178 attach_pid(p, PIDTYPE_PID, p->pid);
1179 attach_pid(p, PIDTYPE_TGID, p->tgid);
1180 if (thread_group_leader(p)) { 1184 if (thread_group_leader(p)) {
1181 p->signal->tty = current->signal->tty; 1185 p->signal->tty = current->signal->tty;
1182 p->signal->pgrp = process_group(current); 1186 p->signal->pgrp = process_group(current);
@@ -1186,9 +1190,12 @@ static task_t *copy_process(unsigned long clone_flags,
1186 if (p->pid) 1190 if (p->pid)
1187 __get_cpu_var(process_counts)++; 1191 __get_cpu_var(process_counts)++;
1188 } 1192 }
1193 attach_pid(p, PIDTYPE_TGID, p->tgid);
1194 attach_pid(p, PIDTYPE_PID, p->pid);
1189 1195
1190 nr_threads++; 1196 nr_threads++;
1191 total_forks++; 1197 total_forks++;
1198 spin_unlock(&current->sighand->siglock);
1192 write_unlock_irq(&tasklist_lock); 1199 write_unlock_irq(&tasklist_lock);
1193 proc_fork_connector(p); 1200 proc_fork_connector(p);
1194 return p; 1201 return p;