diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-10 19:55:28 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-10 19:55:28 -0500 |
commit | 84abd88a70090cf00f9e45c3a81680874f17626e (patch) | |
tree | 4f58b80057f6e1f5817af1dc33a5458b3dfc9a99 /kernel/fork.c | |
parent | 13ca0fcaa33f6b1984c4111b6ec5df42689fea6f (diff) | |
parent | e28cab42f384745c8a947a9ccd51e4aae52f5d51 (diff) |
Merge remote branch 'linus/master' into x86/bootmem
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 4c20fff8c13a..f88bd984df35 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/magic.h> | 64 | #include <linux/magic.h> |
65 | #include <linux/perf_event.h> | 65 | #include <linux/perf_event.h> |
66 | #include <linux/posix-timers.h> | 66 | #include <linux/posix-timers.h> |
67 | #include <linux/user-return-notifier.h> | ||
67 | 68 | ||
68 | #include <asm/pgtable.h> | 69 | #include <asm/pgtable.h> |
69 | #include <asm/pgalloc.h> | 70 | #include <asm/pgalloc.h> |
@@ -91,7 +92,7 @@ int nr_processes(void) | |||
91 | int cpu; | 92 | int cpu; |
92 | int total = 0; | 93 | int total = 0; |
93 | 94 | ||
94 | for_each_online_cpu(cpu) | 95 | for_each_possible_cpu(cpu) |
95 | total += per_cpu(process_counts, cpu); | 96 | total += per_cpu(process_counts, cpu); |
96 | 97 | ||
97 | return total; | 98 | return total; |
@@ -249,6 +250,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
249 | goto out; | 250 | goto out; |
250 | 251 | ||
251 | setup_thread_stack(tsk, orig); | 252 | setup_thread_stack(tsk, orig); |
253 | clear_user_return_notifier(tsk); | ||
252 | stackend = end_of_stack(tsk); | 254 | stackend = end_of_stack(tsk); |
253 | *stackend = STACK_END_MAGIC; /* for overflow detection */ | 255 | *stackend = STACK_END_MAGIC; /* for overflow detection */ |
254 | 256 | ||
@@ -884,6 +886,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
884 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; | 886 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; |
885 | sig->gtime = cputime_zero; | 887 | sig->gtime = cputime_zero; |
886 | sig->cgtime = cputime_zero; | 888 | sig->cgtime = cputime_zero; |
889 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
890 | sig->prev_utime = sig->prev_stime = cputime_zero; | ||
891 | #endif | ||
887 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; | 892 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; |
888 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; | 893 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; |
889 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; | 894 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; |
@@ -934,9 +939,9 @@ SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) | |||
934 | 939 | ||
935 | static void rt_mutex_init_task(struct task_struct *p) | 940 | static void rt_mutex_init_task(struct task_struct *p) |
936 | { | 941 | { |
937 | spin_lock_init(&p->pi_lock); | 942 | raw_spin_lock_init(&p->pi_lock); |
938 | #ifdef CONFIG_RT_MUTEXES | 943 | #ifdef CONFIG_RT_MUTEXES |
939 | plist_head_init(&p->pi_waiters, &p->pi_lock); | 944 | plist_head_init_raw(&p->pi_waiters, &p->pi_lock); |
940 | p->pi_blocked_on = NULL; | 945 | p->pi_blocked_on = NULL; |
941 | #endif | 946 | #endif |
942 | } | 947 | } |
@@ -1066,8 +1071,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1066 | p->gtime = cputime_zero; | 1071 | p->gtime = cputime_zero; |
1067 | p->utimescaled = cputime_zero; | 1072 | p->utimescaled = cputime_zero; |
1068 | p->stimescaled = cputime_zero; | 1073 | p->stimescaled = cputime_zero; |
1074 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
1069 | p->prev_utime = cputime_zero; | 1075 | p->prev_utime = cputime_zero; |
1070 | p->prev_stime = cputime_zero; | 1076 | p->prev_stime = cputime_zero; |
1077 | #endif | ||
1071 | 1078 | ||
1072 | p->default_timer_slack_ns = current->timer_slack_ns; | 1079 | p->default_timer_slack_ns = current->timer_slack_ns; |
1073 | 1080 | ||
@@ -1120,6 +1127,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1120 | #ifdef CONFIG_DEBUG_MUTEXES | 1127 | #ifdef CONFIG_DEBUG_MUTEXES |
1121 | p->blocked_on = NULL; /* not blocked yet */ | 1128 | p->blocked_on = NULL; /* not blocked yet */ |
1122 | #endif | 1129 | #endif |
1130 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | ||
1131 | p->memcg_batch.do_batch = 0; | ||
1132 | p->memcg_batch.memcg = NULL; | ||
1133 | #endif | ||
1123 | 1134 | ||
1124 | p->bts = NULL; | 1135 | p->bts = NULL; |
1125 | 1136 | ||
@@ -1199,9 +1210,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1199 | p->sas_ss_sp = p->sas_ss_size = 0; | 1210 | p->sas_ss_sp = p->sas_ss_size = 0; |
1200 | 1211 | ||
1201 | /* | 1212 | /* |
1202 | * Syscall tracing should be turned off in the child regardless | 1213 | * Syscall tracing and stepping should be turned off in the |
1203 | * of CLONE_PTRACE. | 1214 | * child regardless of CLONE_PTRACE. |
1204 | */ | 1215 | */ |
1216 | user_disable_single_step(p); | ||
1205 | clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); | 1217 | clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); |
1206 | #ifdef TIF_SYSCALL_EMU | 1218 | #ifdef TIF_SYSCALL_EMU |
1207 | clear_tsk_thread_flag(p, TIF_SYSCALL_EMU); | 1219 | clear_tsk_thread_flag(p, TIF_SYSCALL_EMU); |
@@ -1229,21 +1241,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1229 | /* Need tasklist lock for parent etc handling! */ | 1241 | /* Need tasklist lock for parent etc handling! */ |
1230 | write_lock_irq(&tasklist_lock); | 1242 | write_lock_irq(&tasklist_lock); |
1231 | 1243 | ||
1232 | /* | ||
1233 | * The task hasn't been attached yet, so its cpus_allowed mask will | ||
1234 | * not be changed, nor will its assigned CPU. | ||
1235 | * | ||
1236 | * The cpus_allowed mask of the parent may have changed after it was | ||
1237 | * copied first time - so re-copy it here, then check the child's CPU | ||
1238 | * to ensure it is on a valid CPU (and if not, just force it back to | ||
1239 | * parent's CPU). This avoids alot of nasty races. | ||
1240 | */ | ||
1241 | p->cpus_allowed = current->cpus_allowed; | ||
1242 | p->rt.nr_cpus_allowed = current->rt.nr_cpus_allowed; | ||
1243 | if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed) || | ||
1244 | !cpu_online(task_cpu(p)))) | ||
1245 | set_task_cpu(p, smp_processor_id()); | ||
1246 | |||
1247 | /* CLONE_PARENT re-uses the old parent */ | 1244 | /* CLONE_PARENT re-uses the old parent */ |
1248 | if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { | 1245 | if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { |
1249 | p->real_parent = current->real_parent; | 1246 | p->real_parent = current->real_parent; |
@@ -1279,7 +1276,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1279 | } | 1276 | } |
1280 | 1277 | ||
1281 | if (likely(p->pid)) { | 1278 | if (likely(p->pid)) { |
1282 | list_add_tail(&p->sibling, &p->real_parent->children); | ||
1283 | tracehook_finish_clone(p, clone_flags, trace); | 1279 | tracehook_finish_clone(p, clone_flags, trace); |
1284 | 1280 | ||
1285 | if (thread_group_leader(p)) { | 1281 | if (thread_group_leader(p)) { |
@@ -1291,6 +1287,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1291 | p->signal->tty = tty_kref_get(current->signal->tty); | 1287 | p->signal->tty = tty_kref_get(current->signal->tty); |
1292 | attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); | 1288 | attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); |
1293 | attach_pid(p, PIDTYPE_SID, task_session(current)); | 1289 | attach_pid(p, PIDTYPE_SID, task_session(current)); |
1290 | list_add_tail(&p->sibling, &p->real_parent->children); | ||
1294 | list_add_tail_rcu(&p->tasks, &init_task.tasks); | 1291 | list_add_tail_rcu(&p->tasks, &init_task.tasks); |
1295 | __get_cpu_var(process_counts)++; | 1292 | __get_cpu_var(process_counts)++; |
1296 | } | 1293 | } |
@@ -1310,7 +1307,8 @@ bad_fork_free_pid: | |||
1310 | if (pid != &init_struct_pid) | 1307 | if (pid != &init_struct_pid) |
1311 | free_pid(pid); | 1308 | free_pid(pid); |
1312 | bad_fork_cleanup_io: | 1309 | bad_fork_cleanup_io: |
1313 | put_io_context(p->io_context); | 1310 | if (p->io_context) |
1311 | exit_io_context(p); | ||
1314 | bad_fork_cleanup_namespaces: | 1312 | bad_fork_cleanup_namespaces: |
1315 | exit_task_namespaces(p); | 1313 | exit_task_namespaces(p); |
1316 | bad_fork_cleanup_mm: | 1314 | bad_fork_cleanup_mm: |