aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index b9e2edd00726..4430eb1376f2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -61,8 +61,8 @@
61#include <linux/proc_fs.h> 61#include <linux/proc_fs.h>
62#include <linux/blkdev.h> 62#include <linux/blkdev.h>
63#include <linux/fs_struct.h> 63#include <linux/fs_struct.h>
64#include <trace/sched.h>
65#include <linux/magic.h> 64#include <linux/magic.h>
65#include <linux/perf_counter.h>
66 66
67#include <asm/pgtable.h> 67#include <asm/pgtable.h>
68#include <asm/pgalloc.h> 68#include <asm/pgalloc.h>
@@ -71,6 +71,8 @@
71#include <asm/cacheflush.h> 71#include <asm/cacheflush.h>
72#include <asm/tlbflush.h> 72#include <asm/tlbflush.h>
73 73
74#include <trace/events/sched.h>
75
74/* 76/*
75 * Protected counters by write_lock_irq(&tasklist_lock) 77 * Protected counters by write_lock_irq(&tasklist_lock)
76 */ 78 */
@@ -83,8 +85,6 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0;
83 85
84__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ 86__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
85 87
86DEFINE_TRACE(sched_process_fork);
87
88int nr_processes(void) 88int nr_processes(void)
89{ 89{
90 int cpu; 90 int cpu;
@@ -982,6 +982,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
982 if (!p) 982 if (!p)
983 goto fork_out; 983 goto fork_out;
984 984
985 ftrace_graph_init_task(p);
986
985 rt_mutex_init_task(p); 987 rt_mutex_init_task(p);
986 988
987#ifdef CONFIG_PROVE_LOCKING 989#ifdef CONFIG_PROVE_LOCKING
@@ -1089,12 +1091,16 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1089#ifdef CONFIG_DEBUG_MUTEXES 1091#ifdef CONFIG_DEBUG_MUTEXES
1090 p->blocked_on = NULL; /* not blocked yet */ 1092 p->blocked_on = NULL; /* not blocked yet */
1091#endif 1093#endif
1092 if (unlikely(current->ptrace)) 1094
1093 ptrace_fork(p, clone_flags); 1095 p->bts = NULL;
1094 1096
1095 /* Perform scheduler related setup. Assign this task to a CPU. */ 1097 /* Perform scheduler related setup. Assign this task to a CPU. */
1096 sched_fork(p, clone_flags); 1098 sched_fork(p, clone_flags);
1097 1099
1100 retval = perf_counter_init_task(p);
1101 if (retval)
1102 goto bad_fork_cleanup_policy;
1103
1098 if ((retval = audit_alloc(p))) 1104 if ((retval = audit_alloc(p)))
1099 goto bad_fork_cleanup_policy; 1105 goto bad_fork_cleanup_policy;
1100 /* copy all the process information */ 1106 /* copy all the process information */
@@ -1131,8 +1137,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1131 } 1137 }
1132 } 1138 }
1133 1139
1134 ftrace_graph_init_task(p);
1135
1136 p->pid = pid_nr(pid); 1140 p->pid = pid_nr(pid);
1137 p->tgid = p->pid; 1141 p->tgid = p->pid;
1138 if (clone_flags & CLONE_THREAD) 1142 if (clone_flags & CLONE_THREAD)
@@ -1141,7 +1145,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1141 if (current->nsproxy != p->nsproxy) { 1145 if (current->nsproxy != p->nsproxy) {
1142 retval = ns_cgroup_clone(p, pid); 1146 retval = ns_cgroup_clone(p, pid);
1143 if (retval) 1147 if (retval)
1144 goto bad_fork_free_graph; 1148 goto bad_fork_free_pid;
1145 } 1149 }
1146 1150
1147 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; 1151 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
@@ -1233,7 +1237,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1233 spin_unlock(&current->sighand->siglock); 1237 spin_unlock(&current->sighand->siglock);
1234 write_unlock_irq(&tasklist_lock); 1238 write_unlock_irq(&tasklist_lock);
1235 retval = -ERESTARTNOINTR; 1239 retval = -ERESTARTNOINTR;
1236 goto bad_fork_free_graph; 1240 goto bad_fork_free_pid;
1237 } 1241 }
1238 1242
1239 if (clone_flags & CLONE_THREAD) { 1243 if (clone_flags & CLONE_THREAD) {
@@ -1268,8 +1272,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1268 cgroup_post_fork(p); 1272 cgroup_post_fork(p);
1269 return p; 1273 return p;
1270 1274
1271bad_fork_free_graph:
1272 ftrace_graph_exit_task(p);
1273bad_fork_free_pid: 1275bad_fork_free_pid:
1274 if (pid != &init_struct_pid) 1276 if (pid != &init_struct_pid)
1275 free_pid(pid); 1277 free_pid(pid);
@@ -1293,6 +1295,7 @@ bad_fork_cleanup_semundo:
1293bad_fork_cleanup_audit: 1295bad_fork_cleanup_audit:
1294 audit_free(p); 1296 audit_free(p);
1295bad_fork_cleanup_policy: 1297bad_fork_cleanup_policy:
1298 perf_counter_free_task(p);
1296#ifdef CONFIG_NUMA 1299#ifdef CONFIG_NUMA
1297 mpol_put(p->mempolicy); 1300 mpol_put(p->mempolicy);
1298bad_fork_cleanup_cgroup: 1301bad_fork_cleanup_cgroup:
@@ -1406,10 +1409,16 @@ long do_fork(unsigned long clone_flags,
1406 if (clone_flags & CLONE_VFORK) { 1409 if (clone_flags & CLONE_VFORK) {
1407 p->vfork_done = &vfork; 1410 p->vfork_done = &vfork;
1408 init_completion(&vfork); 1411 init_completion(&vfork);
1412 } else if (!(clone_flags & CLONE_VM)) {
1413 /*
1414 * vfork will do an exec which will call
1415 * set_task_comm()
1416 */
1417 perf_counter_fork(p);
1409 } 1418 }
1410 1419
1411 audit_finish_fork(p); 1420 audit_finish_fork(p);
1412 tracehook_report_clone(trace, regs, clone_flags, nr, p); 1421 tracehook_report_clone(regs, clone_flags, nr, p);
1413 1422
1414 /* 1423 /*
1415 * We set PF_STARTING at creation in case tracing wants to 1424 * We set PF_STARTING at creation in case tracing wants to