diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 19 |
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 | } |
109 | EXPORT_SYMBOL(free_task); | 109 | EXPORT_SYMBOL(free_task); |
110 | 110 | ||
111 | void __put_task_struct(struct task_struct *tsk) | 111 | void __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(¤t->sighand->siglock); | ||
1126 | if (clone_flags & CLONE_THREAD) { | 1135 | if (clone_flags & CLONE_THREAD) { |
1127 | spin_lock(¤t->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(¤t->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(¤t->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; |