Blame view
kernel/fork.c
49.7 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 |
/* * linux/kernel/fork.c * * Copyright (C) 1991, 1992 Linus Torvalds */ /* * 'fork.c' contains the help-routines for the 'fork' system call * (see also entry.S and others). * Fork is rather simple, once you get the hang of it, but the memory * management can be a bitch. See 'mm/memory.c': 'copy_page_range()' */ |
1da177e4c Linux-2.6.12-rc2 |
13 14 15 |
#include <linux/slab.h> #include <linux/init.h> #include <linux/unistd.h> |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 |
#include <linux/module.h> #include <linux/vmalloc.h> #include <linux/completion.h> |
1da177e4c Linux-2.6.12-rc2 |
19 20 21 22 |
#include <linux/personality.h> #include <linux/mempolicy.h> #include <linux/sem.h> #include <linux/file.h> |
9f3acc314 [PATCH] split lin... |
23 |
#include <linux/fdtable.h> |
da9cbc873 block: blkdev.h c... |
24 |
#include <linux/iocontext.h> |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 |
#include <linux/key.h> #include <linux/binfmts.h> #include <linux/mman.h> |
cddb8a5c1 mmu-notifiers: core |
28 |
#include <linux/mmu_notifier.h> |
1da177e4c Linux-2.6.12-rc2 |
29 |
#include <linux/fs.h> |
615d6e875 mm: per-thread vm... |
30 31 |
#include <linux/mm.h> #include <linux/vmacache.h> |
ab516013a [PATCH] namespace... |
32 |
#include <linux/nsproxy.h> |
c59ede7b7 [PATCH] move capa... |
33 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
34 |
#include <linux/cpu.h> |
b4f48b636 Task Control Grou... |
35 |
#include <linux/cgroup.h> |
1da177e4c Linux-2.6.12-rc2 |
36 |
#include <linux/security.h> |
a1e78772d hugetlb: reserve ... |
37 |
#include <linux/hugetlb.h> |
e2cfabdfd seccomp: add syst... |
38 |
#include <linux/seccomp.h> |
1da177e4c Linux-2.6.12-rc2 |
39 40 41 42 |
#include <linux/swap.h> #include <linux/syscalls.h> #include <linux/jiffies.h> #include <linux/futex.h> |
8141c7f3e Move "exit_robust... |
43 |
#include <linux/compat.h> |
207205a2b kthread: NUMA awa... |
44 |
#include <linux/kthread.h> |
7c3ab7381 [PATCH] io-accoun... |
45 |
#include <linux/task_io_accounting_ops.h> |
ab2af1f50 [PATCH] files: fi... |
46 |
#include <linux/rcupdate.h> |
1da177e4c Linux-2.6.12-rc2 |
47 48 49 |
#include <linux/ptrace.h> #include <linux/mount.h> #include <linux/audit.h> |
78fb74669 Memory controller... |
50 |
#include <linux/memcontrol.h> |
f201ae235 tracing/function-... |
51 |
#include <linux/ftrace.h> |
5e2bf0142 namespaces, pid_n... |
52 |
#include <linux/proc_fs.h> |
1da177e4c Linux-2.6.12-rc2 |
53 54 |
#include <linux/profile.h> #include <linux/rmap.h> |
f8af4da3b ksm: the mm inter... |
55 |
#include <linux/ksm.h> |
1da177e4c Linux-2.6.12-rc2 |
56 |
#include <linux/acct.h> |
8f0ab5147 [PATCH] csa: conv... |
57 |
#include <linux/tsacct_kern.h> |
9f46080c4 [PATCH] Process E... |
58 |
#include <linux/cn_proc.h> |
ba96a0c88 freezer: fix vfor... |
59 |
#include <linux/freezer.h> |
ca74e92b4 [PATCH] per-task-... |
60 |
#include <linux/delayacct.h> |
ad4ecbcba [PATCH] delay acc... |
61 |
#include <linux/taskstats_kern.h> |
0a4254058 [PATCH] Add the c... |
62 |
#include <linux/random.h> |
522ed7767 Audit: add TTY in... |
63 |
#include <linux/tty.h> |
fd0928df9 ioprio: move io p... |
64 |
#include <linux/blkdev.h> |
5ad4e53bd Get rid of indire... |
65 |
#include <linux/fs_struct.h> |
7c9f8861e stackprotector: u... |
66 |
#include <linux/magic.h> |
cdd6c482c perf: Do the big ... |
67 |
#include <linux/perf_event.h> |
42c4ab41a itimers: Merge IT... |
68 |
#include <linux/posix-timers.h> |
8e7cac798 core: Fix user re... |
69 |
#include <linux/user-return-notifier.h> |
3d5992d2a oom: add per-mm o... |
70 |
#include <linux/oom.h> |
ba76149f4 thp: khugepaged |
71 |
#include <linux/khugepaged.h> |
d80e731ec epoll: introduce ... |
72 |
#include <linux/signalfd.h> |
0326f5a94 uprobes/core: Han... |
73 |
#include <linux/uprobes.h> |
a27bb332c aio: don't includ... |
74 |
#include <linux/aio.h> |
52f5684c8 kernel: use macro... |
75 |
#include <linux/compiler.h> |
16db3d3f1 kernel/sysctl.c: ... |
76 |
#include <linux/sysctl.h> |
1da177e4c Linux-2.6.12-rc2 |
77 78 79 80 81 82 83 |
#include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> |
ad8d75fff tracing/events: m... |
84 |
#include <trace/events/sched.h> |
43d2b1132 tracepoint: add t... |
85 86 |
#define CREATE_TRACE_POINTS #include <trace/events/task.h> |
1da177e4c Linux-2.6.12-rc2 |
87 |
/* |
ac1b398de kernel/fork.c: av... |
88 89 90 91 92 93 94 95 96 97 |
* Minimum number of threads to boot the kernel */ #define MIN_THREADS 20 /* * Maximum number of threads */ #define MAX_THREADS FUTEX_TID_MASK /* |
1da177e4c Linux-2.6.12-rc2 |
98 99 100 |
* Protected counters by write_lock_irq(&tasklist_lock) */ unsigned long total_forks; /* Handle normal Linux uptimes. */ |
fb0a685cb kernel/fork.c: fi... |
101 |
int nr_threads; /* The idle threads do not count.. */ |
1da177e4c Linux-2.6.12-rc2 |
102 103 104 105 |
int max_threads; /* tunable limit on nr_threads */ DEFINE_PER_CPU(unsigned long, process_counts) = 0; |
c59923a15 [PATCH] remove th... |
106 |
__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ |
db1466b3e rcu: Use wrapper ... |
107 108 109 110 111 112 113 114 |
#ifdef CONFIG_PROVE_RCU int lockdep_tasklist_lock_is_held(void) { return lockdep_is_held(&tasklist_lock); } EXPORT_SYMBOL_GPL(lockdep_tasklist_lock_is_held); #endif /* #ifdef CONFIG_PROVE_RCU */ |
1da177e4c Linux-2.6.12-rc2 |
115 116 117 118 119 |
int nr_processes(void) { int cpu; int total = 0; |
1d5107509 Correct nr_proces... |
120 |
for_each_possible_cpu(cpu) |
1da177e4c Linux-2.6.12-rc2 |
121 122 123 124 |
total += per_cpu(process_counts, cpu); return total; } |
f19b9f74b fork: fix error h... |
125 126 127 |
void __weak arch_release_task_struct(struct task_struct *tsk) { } |
f5e102873 task_allocator: U... |
128 |
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR |
e18b890bb [PATCH] slab: rem... |
129 |
static struct kmem_cache *task_struct_cachep; |
41101809a fork: Provide wea... |
130 131 132 133 134 |
static inline struct task_struct *alloc_task_struct_node(int node) { return kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node); } |
41101809a fork: Provide wea... |
135 136 |
static inline void free_task_struct(struct task_struct *tsk) { |
41101809a fork: Provide wea... |
137 138 |
kmem_cache_free(task_struct_cachep, tsk); } |
1da177e4c Linux-2.6.12-rc2 |
139 |
#endif |
f19b9f74b fork: fix error h... |
140 141 142 |
void __weak arch_release_thread_info(struct thread_info *ti) { } |
f5e102873 task_allocator: U... |
143 |
#ifndef CONFIG_ARCH_THREAD_INFO_ALLOCATOR |
41101809a fork: Provide wea... |
144 |
|
0d15d74a1 fork: Provide kme... |
145 146 147 148 149 |
/* * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a * kmemcache based allocator. */ # if THREAD_SIZE >= PAGE_SIZE |
b6a84016b mm: NUMA aware al... |
150 151 |
static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) |
b69c49b78 clean up duplicat... |
152 |
{ |
52383431b mm: get rid of __... |
153 154 |
struct page *page = alloc_kmem_pages_node(node, THREADINFO_GFP, THREAD_SIZE_ORDER); |
b6a84016b mm: NUMA aware al... |
155 156 |
return page ? page_address(page) : NULL; |
b69c49b78 clean up duplicat... |
157 158 159 160 |
} static inline void free_thread_info(struct thread_info *ti) { |
52383431b mm: get rid of __... |
161 |
free_kmem_pages((unsigned long)ti, THREAD_SIZE_ORDER); |
b69c49b78 clean up duplicat... |
162 |
} |
0d15d74a1 fork: Provide kme... |
163 164 165 166 167 168 169 170 171 172 173 |
# else static struct kmem_cache *thread_info_cache; static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node) { return kmem_cache_alloc_node(thread_info_cache, THREADINFO_GFP, node); } static void free_thread_info(struct thread_info *ti) { |
0d15d74a1 fork: Provide kme... |
174 175 176 177 178 179 180 181 182 183 |
kmem_cache_free(thread_info_cache, ti); } void thread_info_cache_init(void) { thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, THREAD_SIZE, 0, NULL); BUG_ON(thread_info_cache == NULL); } # endif |
b69c49b78 clean up duplicat... |
184 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
185 |
/* SLAB cache for signal_struct structures (tsk->signal) */ |
e18b890bb [PATCH] slab: rem... |
186 |
static struct kmem_cache *signal_cachep; |
1da177e4c Linux-2.6.12-rc2 |
187 188 |
/* SLAB cache for sighand_struct structures (tsk->sighand) */ |
e18b890bb [PATCH] slab: rem... |
189 |
struct kmem_cache *sighand_cachep; |
1da177e4c Linux-2.6.12-rc2 |
190 191 |
/* SLAB cache for files_struct structures (tsk->files) */ |
e18b890bb [PATCH] slab: rem... |
192 |
struct kmem_cache *files_cachep; |
1da177e4c Linux-2.6.12-rc2 |
193 194 |
/* SLAB cache for fs_struct structures (tsk->fs) */ |
e18b890bb [PATCH] slab: rem... |
195 |
struct kmem_cache *fs_cachep; |
1da177e4c Linux-2.6.12-rc2 |
196 197 |
/* SLAB cache for vm_area_struct structures */ |
e18b890bb [PATCH] slab: rem... |
198 |
struct kmem_cache *vm_area_cachep; |
1da177e4c Linux-2.6.12-rc2 |
199 200 |
/* SLAB cache for mm_struct structures (tsk->mm) */ |
e18b890bb [PATCH] slab: rem... |
201 |
static struct kmem_cache *mm_cachep; |
1da177e4c Linux-2.6.12-rc2 |
202 |
|
c6a7f5728 mm: oom analysis:... |
203 204 205 206 207 208 |
static void account_kernel_stack(struct thread_info *ti, int account) { struct zone *zone = page_zone(virt_to_page(ti)); mod_zone_page_state(zone, NR_KERNEL_STACK, account); } |
1da177e4c Linux-2.6.12-rc2 |
209 210 |
void free_task(struct task_struct *tsk) { |
c6a7f5728 mm: oom analysis:... |
211 |
account_kernel_stack(tsk->stack, -1); |
f19b9f74b fork: fix error h... |
212 |
arch_release_thread_info(tsk->stack); |
f7e4217b0 rename thread_inf... |
213 |
free_thread_info(tsk->stack); |
23f78d4a0 [PATCH] pi-futex:... |
214 |
rt_mutex_debug_task_free(tsk); |
fb52607af tracing/function-... |
215 |
ftrace_graph_exit_task(tsk); |
e2cfabdfd seccomp: add syst... |
216 |
put_seccomp_filter(tsk); |
f19b9f74b fork: fix error h... |
217 |
arch_release_task_struct(tsk); |
1da177e4c Linux-2.6.12-rc2 |
218 219 220 |
free_task_struct(tsk); } EXPORT_SYMBOL(free_task); |
ea6d290ca signals: make tas... |
221 222 |
static inline void free_signal_struct(struct signal_struct *sig) { |
97101eb41 exit: move taskst... |
223 |
taskstats_tgid_free(sig); |
1c5354de9 sched: Move sched... |
224 |
sched_autogroup_exit(sig); |
ea6d290ca signals: make tas... |
225 226 227 228 229 |
kmem_cache_free(signal_cachep, sig); } static inline void put_signal_struct(struct signal_struct *sig) { |
1c5354de9 sched: Move sched... |
230 |
if (atomic_dec_and_test(&sig->sigcnt)) |
ea6d290ca signals: make tas... |
231 232 |
free_signal_struct(sig); } |
158d9ebd1 [PATCH] resurrect... |
233 |
void __put_task_struct(struct task_struct *tsk) |
1da177e4c Linux-2.6.12-rc2 |
234 |
{ |
270f722d4 Fix tsk->exit_sta... |
235 |
WARN_ON(!tsk->exit_state); |
1da177e4c Linux-2.6.12-rc2 |
236 237 |
WARN_ON(atomic_read(&tsk->usage)); WARN_ON(tsk == current); |
156654f49 sched/numa: Move ... |
238 |
task_numa_free(tsk); |
1a2a4d06e security: create ... |
239 |
security_task_free(tsk); |
e0e817392 CRED: Add some co... |
240 |
exit_creds(tsk); |
35df17c57 [PATCH] task dela... |
241 |
delayacct_tsk_free(tsk); |
ea6d290ca signals: make tas... |
242 |
put_signal_struct(tsk->signal); |
1da177e4c Linux-2.6.12-rc2 |
243 244 245 246 |
if (!profile_handoff_task(tsk)) free_task(tsk); } |
77c100c83 export pid symbol... |
247 |
EXPORT_SYMBOL_GPL(__put_task_struct); |
1da177e4c Linux-2.6.12-rc2 |
248 |
|
6c0a9fa62 fork: Remove the ... |
249 |
void __init __weak arch_task_cache_init(void) { } |
61c4628b5 x86, fpu: split F... |
250 |
|
ff691f6e0 kernel/fork.c: ne... |
251 252 253 |
/* * set_max_threads */ |
16db3d3f1 kernel/sysctl.c: ... |
254 |
static void set_max_threads(unsigned int max_threads_suggested) |
ff691f6e0 kernel/fork.c: ne... |
255 |
{ |
ac1b398de kernel/fork.c: av... |
256 |
u64 threads; |
ff691f6e0 kernel/fork.c: ne... |
257 258 |
/* |
ac1b398de kernel/fork.c: av... |
259 260 |
* The number of threads shall be limited such that the thread * structures may only consume a small part of the available memory. |
ff691f6e0 kernel/fork.c: ne... |
261 |
*/ |
ac1b398de kernel/fork.c: av... |
262 263 264 265 266 |
if (fls64(totalram_pages) + fls64(PAGE_SIZE) > 64) threads = MAX_THREADS; else threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE, (u64) THREAD_SIZE * 8UL); |
16db3d3f1 kernel/sysctl.c: ... |
267 268 |
if (threads > max_threads_suggested) threads = max_threads_suggested; |
ac1b398de kernel/fork.c: av... |
269 |
max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS); |
ff691f6e0 kernel/fork.c: ne... |
270 271 272 |
} void __init fork_init(void) |
1da177e4c Linux-2.6.12-rc2 |
273 |
{ |
f5e102873 task_allocator: U... |
274 |
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR |
1da177e4c Linux-2.6.12-rc2 |
275 276 277 278 279 280 |
#ifndef ARCH_MIN_TASKALIGN #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES #endif /* create a slab on which task_structs can be allocated */ task_struct_cachep = kmem_cache_create("task_struct", sizeof(struct task_struct), |
2dff44052 kmemcheck: add mm... |
281 |
ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL); |
1da177e4c Linux-2.6.12-rc2 |
282 |
#endif |
61c4628b5 x86, fpu: split F... |
283 284 |
/* do the arch specific task caches init */ arch_task_cache_init(); |
16db3d3f1 kernel/sysctl.c: ... |
285 |
set_max_threads(MAX_THREADS); |
1da177e4c Linux-2.6.12-rc2 |
286 287 288 289 290 291 |
init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; init_task.signal->rlim[RLIMIT_SIGPENDING] = init_task.signal->rlim[RLIMIT_NPROC]; } |
52f5684c8 kernel: use macro... |
292 |
int __weak arch_dup_task_struct(struct task_struct *dst, |
61c4628b5 x86, fpu: split F... |
293 294 295 296 297 |
struct task_struct *src) { *dst = *src; return 0; } |
d4311ff1a init/main.c: Give... |
298 299 300 301 302 303 304 |
void set_task_stack_end_magic(struct task_struct *tsk) { unsigned long *stackend; stackend = end_of_stack(tsk); *stackend = STACK_END_MAGIC; /* for overflow detection */ } |
1da177e4c Linux-2.6.12-rc2 |
305 306 307 308 |
static struct task_struct *dup_task_struct(struct task_struct *orig) { struct task_struct *tsk; struct thread_info *ti; |
207205a2b kthread: NUMA awa... |
309 |
int node = tsk_fork_get_node(orig); |
3e26c149c mm: dirty balanci... |
310 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
311 |
|
504f52b54 mm: NUMA aware al... |
312 |
tsk = alloc_task_struct_node(node); |
1da177e4c Linux-2.6.12-rc2 |
313 314 |
if (!tsk) return NULL; |
b6a84016b mm: NUMA aware al... |
315 |
ti = alloc_thread_info_node(tsk, node); |
f19b9f74b fork: fix error h... |
316 317 |
if (!ti) goto free_tsk; |
1da177e4c Linux-2.6.12-rc2 |
318 |
|
fb0a685cb kernel/fork.c: fi... |
319 |
err = arch_dup_task_struct(tsk, orig); |
164c33c6a sched: Fix fork()... |
320 |
if (err) |
f19b9f74b fork: fix error h... |
321 |
goto free_ti; |
164c33c6a sched: Fix fork()... |
322 |
|
87bec58a5 revert "sched: Fi... |
323 |
tsk->stack = ti; |
dbd952127 seccomp: introduc... |
324 325 326 327 328 329 330 331 332 |
#ifdef CONFIG_SECCOMP /* * We must handle setting up seccomp filters once we're under * the sighand lock in case orig has changed between now and * then. Until then, filter must be NULL to avoid messing up * the usage counts on the error path calling free_task. */ tsk->seccomp.filter = NULL; #endif |
87bec58a5 revert "sched: Fi... |
333 334 |
setup_thread_stack(tsk, orig); |
8e7cac798 core: Fix user re... |
335 |
clear_user_return_notifier(tsk); |
f26f9aff6 Sched: fix skip_c... |
336 |
clear_tsk_need_resched(tsk); |
d4311ff1a init/main.c: Give... |
337 |
set_task_stack_end_magic(tsk); |
1da177e4c Linux-2.6.12-rc2 |
338 |
|
0a4254058 [PATCH] Add the c... |
339 340 341 |
#ifdef CONFIG_CC_STACKPROTECTOR tsk->stack_canary = get_random_int(); #endif |
fb0a685cb kernel/fork.c: fi... |
342 343 344 345 346 |
/* * One for us, one for whoever does the "release_task()" (usually * parent) */ atomic_set(&tsk->usage, 2); |
6c5c93415 [PATCH] ifdef blk... |
347 |
#ifdef CONFIG_BLK_DEV_IO_TRACE |
2056a782f [PATCH] Block que... |
348 |
tsk->btrace_seq = 0; |
6c5c93415 [PATCH] ifdef blk... |
349 |
#endif |
a0aa7f68a [PATCH] Don't inh... |
350 |
tsk->splice_pipe = NULL; |
5640f7685 net: use a per ta... |
351 |
tsk->task_frag.page = NULL; |
c6a7f5728 mm: oom analysis:... |
352 353 |
account_kernel_stack(ti, 1); |
1da177e4c Linux-2.6.12-rc2 |
354 |
return tsk; |
61c4628b5 x86, fpu: split F... |
355 |
|
f19b9f74b fork: fix error h... |
356 |
free_ti: |
61c4628b5 x86, fpu: split F... |
357 |
free_thread_info(ti); |
f19b9f74b fork: fix error h... |
358 |
free_tsk: |
61c4628b5 x86, fpu: split F... |
359 360 |
free_task_struct(tsk); return NULL; |
1da177e4c Linux-2.6.12-rc2 |
361 362 363 |
} #ifdef CONFIG_MMU |
a39bc5169 Uninline fork.c/e... |
364 |
static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) |
1da177e4c Linux-2.6.12-rc2 |
365 |
{ |
297c5eee3 mm: make the vma ... |
366 |
struct vm_area_struct *mpnt, *tmp, *prev, **pprev; |
1da177e4c Linux-2.6.12-rc2 |
367 368 369 |
struct rb_node **rb_link, *rb_parent; int retval; unsigned long charge; |
1da177e4c Linux-2.6.12-rc2 |
370 |
|
32cdba1e0 uprobes: Use perc... |
371 |
uprobe_start_dup_mmap(); |
1da177e4c Linux-2.6.12-rc2 |
372 |
down_write(&oldmm->mmap_sem); |
ec8c0446b [PATCH] Optimize ... |
373 |
flush_cache_dup_mm(oldmm); |
f8ac4ec9c uprobes: Introduc... |
374 |
uprobe_dup_mmap(oldmm, mm); |
ad3394517 [PATCH] lockdep: ... |
375 376 377 378 |
/* * Not linked in yet - no deadlock potential: */ down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING); |
7ee782325 [PATCH] mm: dup_m... |
379 |
|
90f31d0ea mm: rcu-protected... |
380 381 |
/* No ordering required: file already has been exposed. */ RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); |
4f7d46143 fork: copy mm's v... |
382 383 384 385 |
mm->total_vm = oldmm->total_vm; mm->shared_vm = oldmm->shared_vm; mm->exec_vm = oldmm->exec_vm; mm->stack_vm = oldmm->stack_vm; |
1da177e4c Linux-2.6.12-rc2 |
386 387 388 |
rb_link = &mm->mm_rb.rb_node; rb_parent = NULL; pprev = &mm->mmap; |
f8af4da3b ksm: the mm inter... |
389 390 391 |
retval = ksm_fork(mm, oldmm); if (retval) goto out; |
ba76149f4 thp: khugepaged |
392 393 394 |
retval = khugepaged_fork(mm, oldmm); if (retval) goto out; |
1da177e4c Linux-2.6.12-rc2 |
395 |
|
297c5eee3 mm: make the vma ... |
396 |
prev = NULL; |
fd3e42fcc [PATCH] mm: dup_m... |
397 |
for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { |
1da177e4c Linux-2.6.12-rc2 |
398 399 400 |
struct file *file; if (mpnt->vm_flags & VM_DONTCOPY) { |
ab50b8ed8 [PATCH] mm: vm_st... |
401 |
vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file, |
44de9d0ca mm: account the t... |
402 |
-vma_pages(mpnt)); |
1da177e4c Linux-2.6.12-rc2 |
403 404 405 406 |
continue; } charge = 0; if (mpnt->vm_flags & VM_ACCOUNT) { |
b2412b7fa fork: use vma_pag... |
407 |
unsigned long len = vma_pages(mpnt); |
191c54244 mm: collapse secu... |
408 |
if (security_vm_enough_memory_mm(oldmm, len)) /* sic */ |
1da177e4c Linux-2.6.12-rc2 |
409 410 411 |
goto fail_nomem; charge = len; } |
e94b17660 [PATCH] slab: rem... |
412 |
tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
413 414 415 |
if (!tmp) goto fail_nomem; *tmp = *mpnt; |
5beb49305 mm: change anon_v... |
416 |
INIT_LIST_HEAD(&tmp->anon_vma_chain); |
ef0855d33 mm: mempolicy: tu... |
417 418 |
retval = vma_dup_policy(mpnt, tmp); if (retval) |
1da177e4c Linux-2.6.12-rc2 |
419 |
goto fail_nomem_policy; |
a247c3a97 rmap: fix walk du... |
420 |
tmp->vm_mm = mm; |
5beb49305 mm: change anon_v... |
421 422 |
if (anon_vma_fork(tmp, mpnt)) goto fail_nomem_anon_vma_fork; |
1da177e4c Linux-2.6.12-rc2 |
423 |
tmp->vm_flags &= ~VM_LOCKED; |
297c5eee3 mm: make the vma ... |
424 |
tmp->vm_next = tmp->vm_prev = NULL; |
1da177e4c Linux-2.6.12-rc2 |
425 426 |
file = tmp->vm_file; if (file) { |
496ad9aa8 new helper: file_... |
427 |
struct inode *inode = file_inode(file); |
b88ed2059 fix mapping_writa... |
428 |
struct address_space *mapping = file->f_mapping; |
1da177e4c Linux-2.6.12-rc2 |
429 430 431 |
get_file(file); if (tmp->vm_flags & VM_DENYWRITE) atomic_dec(&inode->i_writecount); |
83cde9e8b mm: use new helpe... |
432 |
i_mmap_lock_write(mapping); |
b88ed2059 fix mapping_writa... |
433 |
if (tmp->vm_flags & VM_SHARED) |
4bb5f5d93 mm: allow drivers... |
434 |
atomic_inc(&mapping->i_mmap_writable); |
b88ed2059 fix mapping_writa... |
435 436 |
flush_dcache_mmap_lock(mapping); /* insert tmp into the share list, just after mpnt */ |
27ba0644e rmap: drop suppor... |
437 438 |
vma_interval_tree_insert_after(tmp, mpnt, &mapping->i_mmap); |
b88ed2059 fix mapping_writa... |
439 |
flush_dcache_mmap_unlock(mapping); |
83cde9e8b mm: use new helpe... |
440 |
i_mmap_unlock_write(mapping); |
1da177e4c Linux-2.6.12-rc2 |
441 442 443 |
} /* |
a1e78772d hugetlb: reserve ... |
444 445 446 447 448 449 450 451 |
* Clear hugetlb-related page reserves for children. This only * affects MAP_PRIVATE mappings. Faults generated by the child * are not guaranteed to succeed, even if read-only */ if (is_vm_hugetlb_page(tmp)) reset_vma_resv_huge_pages(tmp); /* |
7ee782325 [PATCH] mm: dup_m... |
452 |
* Link in the new vma and copy the page table entries. |
1da177e4c Linux-2.6.12-rc2 |
453 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
454 455 |
*pprev = tmp; pprev = &tmp->vm_next; |
297c5eee3 mm: make the vma ... |
456 457 |
tmp->vm_prev = prev; prev = tmp; |
1da177e4c Linux-2.6.12-rc2 |
458 459 460 461 462 463 |
__vma_link_rb(mm, tmp, rb_link, rb_parent); rb_link = &tmp->vm_rb.rb_right; rb_parent = &tmp->vm_rb; mm->map_count++; |
0b0db14c5 [PATCH] unpaged: ... |
464 |
retval = copy_page_range(mm, oldmm, mpnt); |
1da177e4c Linux-2.6.12-rc2 |
465 466 467 468 469 470 471 |
if (tmp->vm_ops && tmp->vm_ops->open) tmp->vm_ops->open(tmp); if (retval) goto out; } |
d6dd61c83 [PATCH] x86: PARA... |
472 473 |
/* a new mm has just been created */ arch_dup_mmap(oldmm, mm); |
1da177e4c Linux-2.6.12-rc2 |
474 |
retval = 0; |
1da177e4c Linux-2.6.12-rc2 |
475 |
out: |
7ee782325 [PATCH] mm: dup_m... |
476 |
up_write(&mm->mmap_sem); |
fd3e42fcc [PATCH] mm: dup_m... |
477 |
flush_tlb_mm(oldmm); |
1da177e4c Linux-2.6.12-rc2 |
478 |
up_write(&oldmm->mmap_sem); |
32cdba1e0 uprobes: Use perc... |
479 |
uprobe_end_dup_mmap(); |
1da177e4c Linux-2.6.12-rc2 |
480 |
return retval; |
5beb49305 mm: change anon_v... |
481 |
fail_nomem_anon_vma_fork: |
ef0855d33 mm: mempolicy: tu... |
482 |
mpol_put(vma_policy(tmp)); |
1da177e4c Linux-2.6.12-rc2 |
483 484 485 486 487 488 489 |
fail_nomem_policy: kmem_cache_free(vm_area_cachep, tmp); fail_nomem: retval = -ENOMEM; vm_unacct_memory(charge); goto out; } |
fb0a685cb kernel/fork.c: fi... |
490 |
static inline int mm_alloc_pgd(struct mm_struct *mm) |
1da177e4c Linux-2.6.12-rc2 |
491 492 493 494 495 496 |
{ mm->pgd = pgd_alloc(mm); if (unlikely(!mm->pgd)) return -ENOMEM; return 0; } |
fb0a685cb kernel/fork.c: fi... |
497 |
static inline void mm_free_pgd(struct mm_struct *mm) |
1da177e4c Linux-2.6.12-rc2 |
498 |
{ |
5e5419734 add mm argument t... |
499 |
pgd_free(mm, mm->pgd); |
1da177e4c Linux-2.6.12-rc2 |
500 501 |
} #else |
90f31d0ea mm: rcu-protected... |
502 503 504 505 506 507 508 |
static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) { down_write(&oldmm->mmap_sem); RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); up_write(&oldmm->mmap_sem); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
509 510 511 |
#define mm_alloc_pgd(mm) (0) #define mm_free_pgd(mm) #endif /* CONFIG_MMU */ |
23ff44402 whitespace fixes:... |
512 |
__cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock); |
1da177e4c Linux-2.6.12-rc2 |
513 |
|
e94b17660 [PATCH] slab: rem... |
514 |
#define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL)) |
1da177e4c Linux-2.6.12-rc2 |
515 |
#define free_mm(mm) (kmem_cache_free(mm_cachep, (mm))) |
4cb0e11b1 coredump_filter: ... |
516 517 518 519 520 521 522 523 524 525 526 |
static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT; static int __init coredump_filter_setup(char *s) { default_dump_filter = (simple_strtoul(s, NULL, 0) << MMF_DUMP_FILTER_SHIFT) & MMF_DUMP_FILTER_MASK; return 1; } __setup("coredump_filter=", coredump_filter_setup); |
1da177e4c Linux-2.6.12-rc2 |
527 |
#include <linux/init_task.h> |
858f09930 aio: ifdef fields... |
528 529 530 531 |
static void mm_init_aio(struct mm_struct *mm) { #ifdef CONFIG_AIO spin_lock_init(&mm->ioctx_lock); |
db446a08c aio: convert the ... |
532 |
mm->ioctx_table = NULL; |
858f09930 aio: ifdef fields... |
533 534 |
#endif } |
33144e842 kernel/fork.c: ma... |
535 536 537 538 539 540 |
static void mm_init_owner(struct mm_struct *mm, struct task_struct *p) { #ifdef CONFIG_MEMCG mm->owner = p; #endif } |
fb0a685cb kernel/fork.c: fi... |
541 |
static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) |
1da177e4c Linux-2.6.12-rc2 |
542 |
{ |
41f727fde fork/exec: cleanu... |
543 544 545 |
mm->mmap = NULL; mm->mm_rb = RB_ROOT; mm->vmacache_seqnum = 0; |
1da177e4c Linux-2.6.12-rc2 |
546 547 548 549 |
atomic_set(&mm->mm_users, 1); atomic_set(&mm->mm_count, 1); init_rwsem(&mm->mmap_sem); INIT_LIST_HEAD(&mm->mmlist); |
999d9fc16 coredump: move mm... |
550 |
mm->core_state = NULL; |
e1f56c89b mm: convert mm->n... |
551 |
atomic_long_set(&mm->nr_ptes, 0); |
2d2f5119b mm: do not use mm... |
552 |
mm_nr_pmds_init(mm); |
41f727fde fork/exec: cleanu... |
553 554 |
mm->map_count = 0; mm->locked_vm = 0; |
ce65cefa5 fork: reset mm->p... |
555 |
mm->pinned_vm = 0; |
d559db086 mm: clean up mm_c... |
556 |
memset(&mm->rss_stat, 0, sizeof(mm->rss_stat)); |
1da177e4c Linux-2.6.12-rc2 |
557 |
spin_lock_init(&mm->page_table_lock); |
41f727fde fork/exec: cleanu... |
558 |
mm_init_cpumask(mm); |
858f09930 aio: ifdef fields... |
559 |
mm_init_aio(mm); |
cf475ad28 cgroups: add an o... |
560 |
mm_init_owner(mm, p); |
41f727fde fork/exec: cleanu... |
561 |
mmu_notifier_mm_init(mm); |
208414059 mm: fix TLB flush... |
562 |
clear_tlb_flush_pending(mm); |
41f727fde fork/exec: cleanu... |
563 564 565 |
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS mm->pmd_huge_pte = NULL; #endif |
1da177e4c Linux-2.6.12-rc2 |
566 |
|
a0715cc22 mm, thp: add VM_I... |
567 568 569 570 571 |
if (current->mm) { mm->flags = current->mm->flags & MMF_INIT_MASK; mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK; } else { mm->flags = default_dump_filter; |
1da177e4c Linux-2.6.12-rc2 |
572 |
mm->def_flags = 0; |
a0715cc22 mm, thp: add VM_I... |
573 |
} |
41f727fde fork/exec: cleanu... |
574 575 576 577 578 |
if (mm_alloc_pgd(mm)) goto fail_nopgd; if (init_new_context(p, mm)) goto fail_nocontext; |
78fb74669 Memory controller... |
579 |
|
41f727fde fork/exec: cleanu... |
580 581 582 583 584 |
return mm; fail_nocontext: mm_free_pgd(mm); fail_nopgd: |
1da177e4c Linux-2.6.12-rc2 |
585 586 587 |
free_mm(mm); return NULL; } |
c3f0327f8 mm: add rss count... |
588 589 590 591 592 593 594 595 596 597 598 599 |
static void check_mm(struct mm_struct *mm) { int i; for (i = 0; i < NR_MM_COUNTERS; i++) { long x = atomic_long_read(&mm->rss_stat.count[i]); if (unlikely(x)) printk(KERN_ALERT "BUG: Bad rss-counter state " "mm:%p idx:%d val:%ld ", mm, i, x); } |
b30fe6c7c mm: fix false-pos... |
600 601 602 603 604 605 606 607 608 |
if (atomic_long_read(&mm->nr_ptes)) pr_alert("BUG: non-zero nr_ptes on freeing mm: %ld ", atomic_long_read(&mm->nr_ptes)); if (mm_nr_pmds(mm)) pr_alert("BUG: non-zero nr_pmds on freeing mm: %ld ", mm_nr_pmds(mm)); |
e009bb30c mm: implement spl... |
609 |
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS |
96dad67ff mm: use VM_BUG_ON... |
610 |
VM_BUG_ON_MM(mm->pmd_huge_pte, mm); |
c3f0327f8 mm: add rss count... |
611 612 |
#endif } |
1da177e4c Linux-2.6.12-rc2 |
613 614 615 |
/* * Allocate and initialize an mm_struct. */ |
fb0a685cb kernel/fork.c: fi... |
616 |
struct mm_struct *mm_alloc(void) |
1da177e4c Linux-2.6.12-rc2 |
617 |
{ |
fb0a685cb kernel/fork.c: fi... |
618 |
struct mm_struct *mm; |
1da177e4c Linux-2.6.12-rc2 |
619 620 |
mm = allocate_mm(); |
de03c72cf mm: convert mm->c... |
621 622 623 624 |
if (!mm) return NULL; memset(mm, 0, sizeof(*mm)); |
6345d24da mm: Fix boot cras... |
625 |
return mm_init(mm, current); |
1da177e4c Linux-2.6.12-rc2 |
626 627 628 629 630 631 632 |
} /* * Called when the last reference to the mm * is dropped: either by a lazy thread or by * mmput. Free the page directory and the mm. */ |
7ad5b3a50 kernel: remove fa... |
633 |
void __mmdrop(struct mm_struct *mm) |
1da177e4c Linux-2.6.12-rc2 |
634 635 636 637 |
{ BUG_ON(mm == &init_mm); mm_free_pgd(mm); destroy_context(mm); |
cddb8a5c1 mmu-notifiers: core |
638 |
mmu_notifier_mm_destroy(mm); |
c3f0327f8 mm: add rss count... |
639 |
check_mm(mm); |
1da177e4c Linux-2.6.12-rc2 |
640 641 |
free_mm(mm); } |
6d4e4c4fc KVM: Disallow for... |
642 |
EXPORT_SYMBOL_GPL(__mmdrop); |
1da177e4c Linux-2.6.12-rc2 |
643 644 645 646 647 648 |
/* * Decrement the use count and release all resources for an mm. */ void mmput(struct mm_struct *mm) { |
0ae26f1b3 [PATCH] mmput() m... |
649 |
might_sleep(); |
1da177e4c Linux-2.6.12-rc2 |
650 |
if (atomic_dec_and_test(&mm->mm_users)) { |
d4b3b6384 uprobes/core: All... |
651 |
uprobe_clear_state(mm); |
1da177e4c Linux-2.6.12-rc2 |
652 |
exit_aio(mm); |
1c2fb7a4c ksm: fix deadlock... |
653 |
ksm_exit(mm); |
ba76149f4 thp: khugepaged |
654 |
khugepaged_exit(mm); /* must run before exit_mmap */ |
1da177e4c Linux-2.6.12-rc2 |
655 |
exit_mmap(mm); |
925d1c401 procfs task exe s... |
656 |
set_mm_exe_file(mm, NULL); |
1da177e4c Linux-2.6.12-rc2 |
657 658 659 660 661 |
if (!list_empty(&mm->mmlist)) { spin_lock(&mmlist_lock); list_del(&mm->mmlist); spin_unlock(&mmlist_lock); } |
801460d0c task_struct clean... |
662 663 |
if (mm->binfmt) module_put(mm->binfmt->module); |
1da177e4c Linux-2.6.12-rc2 |
664 665 666 667 |
mmdrop(mm); } } EXPORT_SYMBOL_GPL(mmput); |
90f31d0ea mm: rcu-protected... |
668 669 670 671 672 |
/** * set_mm_exe_file - change a reference to the mm's executable file * * This changes mm's executable file (shown as symlink /proc/[pid]/exe). * |
6e399cd14 prctl: avoid usin... |
673 674 675 676 677 |
* Main users are mmput() and sys_execve(). Callers prevent concurrent * invocations: in mmput() nobody alive left, in execve task is single * threaded. sys_prctl(PR_SET_MM_MAP/EXE_FILE) also needs to set the * mm->exe_file, but does so without using set_mm_exe_file() in order * to do avoid the need for any locks. |
90f31d0ea mm: rcu-protected... |
678 |
*/ |
386460138 mm: extract exe_f... |
679 680 |
void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file) { |
6e399cd14 prctl: avoid usin... |
681 682 683 684 685 686 687 688 |
struct file *old_exe_file; /* * It is safe to dereference the exe_file without RCU as * this function is only called if nobody else can access * this mm -- see comment above for justification. */ old_exe_file = rcu_dereference_raw(mm->exe_file); |
90f31d0ea mm: rcu-protected... |
689 |
|
386460138 mm: extract exe_f... |
690 691 |
if (new_exe_file) get_file(new_exe_file); |
90f31d0ea mm: rcu-protected... |
692 693 694 |
rcu_assign_pointer(mm->exe_file, new_exe_file); if (old_exe_file) fput(old_exe_file); |
386460138 mm: extract exe_f... |
695 |
} |
90f31d0ea mm: rcu-protected... |
696 697 698 699 700 701 |
/** * get_mm_exe_file - acquire a reference to the mm's executable file * * Returns %NULL if mm has no associated executable file. * User must release file via fput(). */ |
386460138 mm: extract exe_f... |
702 703 704 |
struct file *get_mm_exe_file(struct mm_struct *mm) { struct file *exe_file; |
90f31d0ea mm: rcu-protected... |
705 706 707 708 709 |
rcu_read_lock(); exe_file = rcu_dereference(mm->exe_file); if (exe_file && !get_file_rcu(exe_file)) exe_file = NULL; rcu_read_unlock(); |
386460138 mm: extract exe_f... |
710 711 |
return exe_file; } |
11163348a oprofile: reduce ... |
712 |
EXPORT_SYMBOL(get_mm_exe_file); |
386460138 mm: extract exe_f... |
713 |
|
1da177e4c Linux-2.6.12-rc2 |
714 715 716 |
/** * get_task_mm - acquire a reference to the task's mm * |
246bb0b1d kill PF_BORROWED_... |
717 |
* Returns %NULL if the task has no mm. Checks PF_KTHREAD (meaning |
1da177e4c Linux-2.6.12-rc2 |
718 719 720 721 722 723 724 725 726 727 728 729 |
* this kernel workthread has transiently adopted a user mm with use_mm, * to do its AIO) is not set and if so returns a reference to it, after * bumping up the use count. User must release the mm via mmput() * after use. Typically used by /proc and ptrace. */ struct mm_struct *get_task_mm(struct task_struct *task) { struct mm_struct *mm; task_lock(task); mm = task->mm; if (mm) { |
246bb0b1d kill PF_BORROWED_... |
730 |
if (task->flags & PF_KTHREAD) |
1da177e4c Linux-2.6.12-rc2 |
731 732 733 734 735 736 737 738 |
mm = NULL; else atomic_inc(&mm->mm_users); } task_unlock(task); return mm; } EXPORT_SYMBOL_GPL(get_task_mm); |
8cdb878dc Fix race in proce... |
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) { struct mm_struct *mm; int err; err = mutex_lock_killable(&task->signal->cred_guard_mutex); if (err) return ERR_PTR(err); mm = get_task_mm(task); if (mm && mm != current->mm && !ptrace_may_access(task, mode)) { mmput(mm); mm = ERR_PTR(-EACCES); } mutex_unlock(&task->signal->cred_guard_mutex); return mm; } |
57b59c4a1 coredump_wait: do... |
758 |
static void complete_vfork_done(struct task_struct *tsk) |
c415c3b47 vfork: introduce ... |
759 |
{ |
d68b46fe1 vfork: make it ki... |
760 |
struct completion *vfork; |
c415c3b47 vfork: introduce ... |
761 |
|
d68b46fe1 vfork: make it ki... |
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 |
task_lock(tsk); vfork = tsk->vfork_done; if (likely(vfork)) { tsk->vfork_done = NULL; complete(vfork); } task_unlock(tsk); } static int wait_for_vfork_done(struct task_struct *child, struct completion *vfork) { int killed; freezer_do_not_count(); killed = wait_for_completion_killable(vfork); freezer_count(); if (killed) { task_lock(child); child->vfork_done = NULL; task_unlock(child); } put_task_struct(child); return killed; |
c415c3b47 vfork: introduce ... |
788 |
} |
1da177e4c Linux-2.6.12-rc2 |
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 |
/* Please note the differences between mmput and mm_release. * mmput is called whenever we stop holding onto a mm_struct, * error success whatever. * * mm_release is called after a mm_struct has been removed * from the current process. * * This difference is important for error handling, when we * only half set up a mm_struct for a new process and need to restore * the old one. Because we mmput the new mm_struct before * restoring the old one. . . * Eric Biederman 10 January 1998 */ void mm_release(struct task_struct *tsk, struct mm_struct *mm) { |
8141c7f3e Move "exit_robust... |
804 805 |
/* Get rid of any futexes when releasing the mm */ #ifdef CONFIG_FUTEX |
fc6b177de futex: Nullify ro... |
806 |
if (unlikely(tsk->robust_list)) { |
8141c7f3e Move "exit_robust... |
807 |
exit_robust_list(tsk); |
fc6b177de futex: Nullify ro... |
808 809 |
tsk->robust_list = NULL; } |
8141c7f3e Move "exit_robust... |
810 |
#ifdef CONFIG_COMPAT |
fc6b177de futex: Nullify ro... |
811 |
if (unlikely(tsk->compat_robust_list)) { |
8141c7f3e Move "exit_robust... |
812 |
compat_exit_robust_list(tsk); |
fc6b177de futex: Nullify ro... |
813 814 |
tsk->compat_robust_list = NULL; } |
8141c7f3e Move "exit_robust... |
815 |
#endif |
322a2c100 futex: Move exit_... |
816 817 |
if (unlikely(!list_empty(&tsk->pi_state_list))) exit_pi_state_list(tsk); |
8141c7f3e Move "exit_robust... |
818 |
#endif |
0326f5a94 uprobes/core: Han... |
819 |
uprobe_free_utask(tsk); |
1da177e4c Linux-2.6.12-rc2 |
820 821 |
/* Get rid of any cached register state */ deactivate_mm(tsk, mm); |
fec1d0115 [PATCH] Disable C... |
822 823 824 825 |
/* * If we're exiting normally, clear a user-space tid field if * requested. We leave this alone when dying by signal, to leave * the value intact in a core dump, and to save the unnecessary |
d68b46fe1 vfork: make it ki... |
826 827 |
* trouble, say, a killed vfork parent shouldn't touch this mm. * Userland only wants this done for a sys_exit. |
fec1d0115 [PATCH] Disable C... |
828 |
*/ |
9c8a8228d execve: must clea... |
829 830 831 832 833 834 835 836 837 838 839 |
if (tsk->clear_child_tid) { if (!(tsk->flags & PF_SIGNALED) && atomic_read(&mm->mm_users) > 1) { /* * We don't check the error code - if userspace has * not set up a proper pointer then tough luck. */ put_user(0, tsk->clear_child_tid); sys_futex(tsk->clear_child_tid, FUTEX_WAKE, 1, NULL, NULL, 0); } |
1da177e4c Linux-2.6.12-rc2 |
840 |
tsk->clear_child_tid = NULL; |
1da177e4c Linux-2.6.12-rc2 |
841 |
} |
f7505d64f fork: call comple... |
842 843 844 845 846 847 848 |
/* * All done, finally we can wake up parent and return this mm to him. * Also kthread_stop() uses this completion for synchronization. */ if (tsk->vfork_done) complete_vfork_done(tsk); |
1da177e4c Linux-2.6.12-rc2 |
849 |
} |
a0a7ec308 [PATCH] unshare s... |
850 851 852 853 |
/* * Allocate a new mm structure and copy contents from the * mm structure of the passed in task structure. */ |
ff252c1fc kernel/fork.c: ma... |
854 |
static struct mm_struct *dup_mm(struct task_struct *tsk) |
a0a7ec308 [PATCH] unshare s... |
855 856 857 |
{ struct mm_struct *mm, *oldmm = current->mm; int err; |
a0a7ec308 [PATCH] unshare s... |
858 859 860 861 862 |
mm = allocate_mm(); if (!mm) goto fail_nomem; memcpy(mm, oldmm, sizeof(*mm)); |
78fb74669 Memory controller... |
863 |
if (!mm_init(mm, tsk)) |
a0a7ec308 [PATCH] unshare s... |
864 |
goto fail_nomem; |
a0a7ec308 [PATCH] unshare s... |
865 866 867 868 869 870 |
err = dup_mmap(mm, oldmm); if (err) goto free_pt; mm->hiwater_rss = get_mm_rss(mm); mm->hiwater_vm = mm->total_vm; |
801460d0c task_struct clean... |
871 872 |
if (mm->binfmt && !try_module_get(mm->binfmt->module)) goto free_pt; |
a0a7ec308 [PATCH] unshare s... |
873 874 875 |
return mm; free_pt: |
801460d0c task_struct clean... |
876 877 |
/* don't put binfmt in mmput, we haven't got module yet */ mm->binfmt = NULL; |
a0a7ec308 [PATCH] unshare s... |
878 879 880 881 |
mmput(mm); fail_nomem: return NULL; |
a0a7ec308 [PATCH] unshare s... |
882 |
} |
fb0a685cb kernel/fork.c: fi... |
883 |
static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) |
1da177e4c Linux-2.6.12-rc2 |
884 |
{ |
fb0a685cb kernel/fork.c: fi... |
885 |
struct mm_struct *mm, *oldmm; |
1da177e4c Linux-2.6.12-rc2 |
886 887 888 889 |
int retval; tsk->min_flt = tsk->maj_flt = 0; tsk->nvcsw = tsk->nivcsw = 0; |
17406b82d softlockup: remov... |
890 891 892 |
#ifdef CONFIG_DETECT_HUNG_TASK tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw; #endif |
1da177e4c Linux-2.6.12-rc2 |
893 894 895 896 897 898 899 900 901 902 903 904 |
tsk->mm = NULL; tsk->active_mm = NULL; /* * Are we cloning a kernel thread? * * We need to steal a active VM for that.. */ oldmm = current->mm; if (!oldmm) return 0; |
615d6e875 mm: per-thread vm... |
905 906 |
/* initialize the new vmacache entries */ vmacache_flush(tsk); |
1da177e4c Linux-2.6.12-rc2 |
907 908 909 |
if (clone_flags & CLONE_VM) { atomic_inc(&oldmm->mm_users); mm = oldmm; |
1da177e4c Linux-2.6.12-rc2 |
910 911 912 913 |
goto good_mm; } retval = -ENOMEM; |
a0a7ec308 [PATCH] unshare s... |
914 |
mm = dup_mm(tsk); |
1da177e4c Linux-2.6.12-rc2 |
915 916 |
if (!mm) goto fail_nomem; |
1da177e4c Linux-2.6.12-rc2 |
917 918 919 920 |
good_mm: tsk->mm = mm; tsk->active_mm = mm; return 0; |
1da177e4c Linux-2.6.12-rc2 |
921 922 |
fail_nomem: return retval; |
1da177e4c Linux-2.6.12-rc2 |
923 |
} |
a39bc5169 Uninline fork.c/e... |
924 |
static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) |
1da177e4c Linux-2.6.12-rc2 |
925 |
{ |
498052bba New locking/refco... |
926 |
struct fs_struct *fs = current->fs; |
1da177e4c Linux-2.6.12-rc2 |
927 |
if (clone_flags & CLONE_FS) { |
498052bba New locking/refco... |
928 |
/* tsk->fs is already what we want */ |
2a4419b5b fs: fs_struct rwl... |
929 |
spin_lock(&fs->lock); |
498052bba New locking/refco... |
930 |
if (fs->in_exec) { |
2a4419b5b fs: fs_struct rwl... |
931 |
spin_unlock(&fs->lock); |
498052bba New locking/refco... |
932 933 934 |
return -EAGAIN; } fs->users++; |
2a4419b5b fs: fs_struct rwl... |
935 |
spin_unlock(&fs->lock); |
1da177e4c Linux-2.6.12-rc2 |
936 937 |
return 0; } |
498052bba New locking/refco... |
938 |
tsk->fs = copy_fs_struct(fs); |
1da177e4c Linux-2.6.12-rc2 |
939 940 941 942 |
if (!tsk->fs) return -ENOMEM; return 0; } |
fb0a685cb kernel/fork.c: fi... |
943 |
static int copy_files(unsigned long clone_flags, struct task_struct *tsk) |
a016f3389 [PATCH] unshare s... |
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 |
{ struct files_struct *oldf, *newf; int error = 0; /* * A background process may not have any files ... */ oldf = current->files; if (!oldf) goto out; if (clone_flags & CLONE_FILES) { atomic_inc(&oldf->count); goto out; } |
a016f3389 [PATCH] unshare s... |
959 960 961 962 963 964 965 966 967 |
newf = dup_fd(oldf, &error); if (!newf) goto out; tsk->files = newf; error = 0; out: return error; } |
fadad878c kernel: add CLONE... |
968 |
static int copy_io(unsigned long clone_flags, struct task_struct *tsk) |
fd0928df9 ioprio: move io p... |
969 970 971 |
{ #ifdef CONFIG_BLOCK struct io_context *ioc = current->io_context; |
6e736be7f block: make ioc g... |
972 |
struct io_context *new_ioc; |
fd0928df9 ioprio: move io p... |
973 974 975 |
if (!ioc) return 0; |
fadad878c kernel: add CLONE... |
976 977 978 979 |
/* * Share io context with parent, if CLONE_IO is set */ if (clone_flags & CLONE_IO) { |
3d48749d9 block: ioc_task_l... |
980 981 |
ioc_task_link(ioc); tsk->io_context = ioc; |
fadad878c kernel: add CLONE... |
982 |
} else if (ioprio_valid(ioc->ioprio)) { |
6e736be7f block: make ioc g... |
983 984 |
new_ioc = get_task_io_context(tsk, GFP_KERNEL, NUMA_NO_NODE); if (unlikely(!new_ioc)) |
fd0928df9 ioprio: move io p... |
985 |
return -ENOMEM; |
6e736be7f block: make ioc g... |
986 |
new_ioc->ioprio = ioc->ioprio; |
11a3122f6 block: strip out ... |
987 |
put_io_context(new_ioc); |
fd0928df9 ioprio: move io p... |
988 989 990 991 |
} #endif return 0; } |
a39bc5169 Uninline fork.c/e... |
992 |
static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) |
1da177e4c Linux-2.6.12-rc2 |
993 994 |
{ struct sighand_struct *sig; |
60348802e fork.c: cleanup f... |
995 |
if (clone_flags & CLONE_SIGHAND) { |
1da177e4c Linux-2.6.12-rc2 |
996 997 998 999 |
atomic_inc(¤t->sighand->count); return 0; } sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); |
e56d09031 [PATCH] RCU signa... |
1000 |
rcu_assign_pointer(tsk->sighand, sig); |
1da177e4c Linux-2.6.12-rc2 |
1001 1002 |
if (!sig) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
1003 1004 1005 1006 |
atomic_set(&sig->count, 1); memcpy(sig->action, current->sighand->action, sizeof(sig->action)); return 0; } |
a7e5328a0 [PATCH] cleanup _... |
1007 |
void __cleanup_sighand(struct sighand_struct *sighand) |
c81addc9d [PATCH] rename __... |
1008 |
{ |
d80e731ec epoll: introduce ... |
1009 1010 |
if (atomic_dec_and_test(&sighand->count)) { signalfd_cleanup(sighand); |
392809b25 signal: Document ... |
1011 1012 1013 1014 |
/* * sighand_cachep is SLAB_DESTROY_BY_RCU so we can free it * without an RCU grace period, see __lock_task_sighand(). */ |
c81addc9d [PATCH] rename __... |
1015 |
kmem_cache_free(sighand_cachep, sighand); |
d80e731ec epoll: introduce ... |
1016 |
} |
c81addc9d [PATCH] rename __... |
1017 |
} |
f06febc96 timers: fix itime... |
1018 1019 1020 1021 1022 |
/* * Initialize POSIX timer handling for a thread group. */ static void posix_cpu_timers_init_group(struct signal_struct *sig) { |
78d7d407b kernel core: use ... |
1023 |
unsigned long cpu_limit; |
f06febc96 timers: fix itime... |
1024 1025 |
/* Thread group counters. */ thread_group_cputime_init(sig); |
78d7d407b kernel core: use ... |
1026 1027 1028 |
cpu_limit = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); if (cpu_limit != RLIM_INFINITY) { sig->cputime_expires.prof_exp = secs_to_cputime(cpu_limit); |
6279a751f posix-timers: fix... |
1029 1030 |
sig->cputimer.running = 1; } |
f06febc96 timers: fix itime... |
1031 1032 1033 1034 1035 |
/* The timer lists. */ INIT_LIST_HEAD(&sig->cpu_timers[0]); INIT_LIST_HEAD(&sig->cpu_timers[1]); INIT_LIST_HEAD(&sig->cpu_timers[2]); } |
a39bc5169 Uninline fork.c/e... |
1036 |
static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) |
1da177e4c Linux-2.6.12-rc2 |
1037 1038 |
{ struct signal_struct *sig; |
1da177e4c Linux-2.6.12-rc2 |
1039 |
|
4ab6c0833 clone(): fix race... |
1040 |
if (clone_flags & CLONE_THREAD) |
490dea45d itimers: remove t... |
1041 |
return 0; |
490dea45d itimers: remove t... |
1042 |
|
a56704ef6 copy_signal() cle... |
1043 |
sig = kmem_cache_zalloc(signal_cachep, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
1044 1045 1046 |
tsk->signal = sig; if (!sig) return -ENOMEM; |
b3ac022cb proc: turn signal... |
1047 |
sig->nr_threads = 1; |
1da177e4c Linux-2.6.12-rc2 |
1048 |
atomic_set(&sig->live, 1); |
b3ac022cb proc: turn signal... |
1049 |
atomic_set(&sig->sigcnt, 1); |
0c740d0af introduce for_eac... |
1050 1051 1052 1053 |
/* list_add(thread_node, thread_head) without INIT_LIST_HEAD() */ sig->thread_head = (struct list_head)LIST_HEAD_INIT(tsk->thread_node); tsk->thread_node = (struct list_head)LIST_HEAD_INIT(sig->thread_head); |
1da177e4c Linux-2.6.12-rc2 |
1054 |
init_waitqueue_head(&sig->wait_chldexit); |
db51aeccd signals: microopt... |
1055 |
sig->curr_target = tsk; |
1da177e4c Linux-2.6.12-rc2 |
1056 1057 |
init_sigpending(&sig->shared_pending); INIT_LIST_HEAD(&sig->posix_timers); |
e78c34967 time, signal: Pro... |
1058 |
seqlock_init(&sig->stats_lock); |
1da177e4c Linux-2.6.12-rc2 |
1059 |
|
c9cb2e3d7 [PATCH] hrtimers:... |
1060 |
hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
1da177e4c Linux-2.6.12-rc2 |
1061 |
sig->real_timer.function = it_real_fn; |
1da177e4c Linux-2.6.12-rc2 |
1062 |
|
1da177e4c Linux-2.6.12-rc2 |
1063 1064 1065 |
task_lock(current->group_leader); memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); task_unlock(current->group_leader); |
6279a751f posix-timers: fix... |
1066 |
posix_cpu_timers_init_group(sig); |
522ed7767 Audit: add TTY in... |
1067 |
tty_audit_fork(sig); |
5091faa44 sched: Add 'autog... |
1068 |
sched_autogroup_fork(sig); |
522ed7767 Audit: add TTY in... |
1069 |
|
4714d1d32 cgroups: read-wri... |
1070 |
#ifdef CONFIG_CGROUPS |
257058ae2 threadgroup: rena... |
1071 |
init_rwsem(&sig->group_rwsem); |
4714d1d32 cgroups: read-wri... |
1072 |
#endif |
a63d83f42 oom: badness heur... |
1073 |
sig->oom_score_adj = current->signal->oom_score_adj; |
dabb16f63 oom: allow a non-... |
1074 |
sig->oom_score_adj_min = current->signal->oom_score_adj_min; |
28b83c519 oom: move oom_adj... |
1075 |
|
ebec18a6d prctl: add PR_{SE... |
1076 1077 |
sig->has_child_subreaper = current->signal->has_child_subreaper || current->signal->is_child_subreaper; |
9b1bf12d5 signals: move cre... |
1078 |
mutex_init(&sig->cred_guard_mutex); |
1da177e4c Linux-2.6.12-rc2 |
1079 1080 |
return 0; } |
dbd952127 seccomp: introduc... |
1081 1082 1083 1084 1085 1086 1087 1088 1089 |
static void copy_seccomp(struct task_struct *p) { #ifdef CONFIG_SECCOMP /* * Must be called with sighand->lock held, which is common to * all threads in the group. Holding cred_guard_mutex is not * needed because this new task is not yet running and cannot * be racing exec. */ |
69f6a34bd seccomp: Replace ... |
1090 |
assert_spin_locked(¤t->sighand->siglock); |
dbd952127 seccomp: introduc... |
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 |
/* Ref-count the new filter user, and assign it. */ get_seccomp_filter(current); p->seccomp = current->seccomp; /* * Explicitly enable no_new_privs here in case it got set * between the task_struct being duplicated and holding the * sighand lock. The seccomp state and nnp must be in sync. */ if (task_no_new_privs(current)) task_set_no_new_privs(p); /* * If the parent gained a seccomp mode after copying thread * flags and between before we held the sighand lock, we have * to manually enable the seccomp thread flag here. */ if (p->seccomp.mode != SECCOMP_MODE_DISABLED) set_tsk_thread_flag(p, TIF_SECCOMP); #endif } |
17da2bd90 [CVE-2009-0029] S... |
1113 |
SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) |
1da177e4c Linux-2.6.12-rc2 |
1114 1115 |
{ current->clear_child_tid = tidptr; |
b488893a3 pid namespaces: c... |
1116 |
return task_pid_vnr(current); |
1da177e4c Linux-2.6.12-rc2 |
1117 |
} |
a39bc5169 Uninline fork.c/e... |
1118 |
static void rt_mutex_init_task(struct task_struct *p) |
23f78d4a0 [PATCH] pi-futex:... |
1119 |
{ |
1d6154825 sched: Convert pi... |
1120 |
raw_spin_lock_init(&p->pi_lock); |
e29e175b0 [PATCH] initialis... |
1121 |
#ifdef CONFIG_RT_MUTEXES |
fb00aca47 rtmutex: Turn the... |
1122 1123 |
p->pi_waiters = RB_ROOT; p->pi_waiters_leftmost = NULL; |
23f78d4a0 [PATCH] pi-futex:... |
1124 |
p->pi_blocked_on = NULL; |
23f78d4a0 [PATCH] pi-futex:... |
1125 1126 |
#endif } |
1da177e4c Linux-2.6.12-rc2 |
1127 |
/* |
f06febc96 timers: fix itime... |
1128 1129 1130 1131 |
* Initialize POSIX timer handling for a single task. */ static void posix_cpu_timers_init(struct task_struct *tsk) { |
648616343 [S390] cputime: a... |
1132 1133 |
tsk->cputime_expires.prof_exp = 0; tsk->cputime_expires.virt_exp = 0; |
f06febc96 timers: fix itime... |
1134 1135 1136 1137 1138 |
tsk->cputime_expires.sched_exp = 0; INIT_LIST_HEAD(&tsk->cpu_timers[0]); INIT_LIST_HEAD(&tsk->cpu_timers[1]); INIT_LIST_HEAD(&tsk->cpu_timers[2]); } |
819077398 kernel/fork.c:cop... |
1139 1140 1141 1142 1143 |
static inline void init_task_pid(struct task_struct *task, enum pid_type type, struct pid *pid) { task->pids[type].pid = pid; } |
f06febc96 timers: fix itime... |
1144 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1145 1146 1147 1148 1149 1150 1151 |
* This creates a new process as a copy of the old one, * but does not actually start it yet. * * It copies the registers, and all the appropriate * parts of the process environment (as per the clone * flags). The actual kick-off is left to the caller. */ |
36c8b5868 [PATCH] sched: cl... |
1152 1153 |
static struct task_struct *copy_process(unsigned long clone_flags, unsigned long stack_start, |
36c8b5868 [PATCH] sched: cl... |
1154 |
unsigned long stack_size, |
36c8b5868 [PATCH] sched: cl... |
1155 |
int __user *child_tidptr, |
09a05394f tracehook: clone |
1156 1157 |
struct pid *pid, int trace) |
1da177e4c Linux-2.6.12-rc2 |
1158 1159 |
{ int retval; |
a24efe62d kernel/fork.c: re... |
1160 |
struct task_struct *p; |
1da177e4c Linux-2.6.12-rc2 |
1161 1162 1163 |
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) return ERR_PTR(-EINVAL); |
e66eded83 userns: Don't all... |
1164 1165 |
if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS)) return ERR_PTR(-EINVAL); |
1da177e4c Linux-2.6.12-rc2 |
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 |
/* * Thread groups must share signals as well, and detached threads * can only be started up within the thread group. */ if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND)) return ERR_PTR(-EINVAL); /* * Shared signal handlers imply shared VM. By way of the above, * thread groups also imply shared VM. Blocking this case allows * for various simplifications in other code. */ if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM)) return ERR_PTR(-EINVAL); |
123be07b0 fork(): disable C... |
1180 1181 1182 1183 1184 1185 1186 1187 1188 |
/* * Siblings of global init remain as zombies on exit since they are * not reaped by their parent (swapper). To solve this and to avoid * multi-rooted process trees, prevent global and container-inits * from creating siblings. */ if ((clone_flags & CLONE_PARENT) && current->signal->flags & SIGNAL_UNKILLABLE) return ERR_PTR(-EINVAL); |
8382fcac1 pidns: Outlaw thr... |
1189 |
/* |
40a0d32d1 fork: unify and t... |
1190 1191 1192 |
* If the new process will be in a different pid or user namespace * do not allow it to share a thread group or signal handlers or * parent with the forking task. |
8382fcac1 pidns: Outlaw thr... |
1193 |
*/ |
1f7f4dde5 fork: Allow CLON... |
1194 |
if (clone_flags & CLONE_SIGHAND) { |
40a0d32d1 fork: unify and t... |
1195 1196 1197 1198 1199 |
if ((clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) || (task_active_pid_ns(current) != current->nsproxy->pid_ns_for_children)) return ERR_PTR(-EINVAL); } |
8382fcac1 pidns: Outlaw thr... |
1200 |
|
1da177e4c Linux-2.6.12-rc2 |
1201 1202 1203 1204 1205 1206 1207 1208 |
retval = security_task_create(clone_flags); if (retval) goto fork_out; retval = -ENOMEM; p = dup_task_struct(current); if (!p) goto fork_out; |
f7e8b616e function-graph: m... |
1209 |
ftrace_graph_init_task(p); |
bea493a03 [PATCH] rt-mutex:... |
1210 |
rt_mutex_init_task(p); |
d12c1a379 lockdep: fix kern... |
1211 |
#ifdef CONFIG_PROVE_LOCKING |
de30a2b35 [PATCH] lockdep: ... |
1212 1213 1214 |
DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); #endif |
1da177e4c Linux-2.6.12-rc2 |
1215 |
retval = -EAGAIN; |
3b11a1dec CRED: Differentia... |
1216 |
if (atomic_read(&p->real_cred->user->processes) >= |
78d7d407b kernel core: use ... |
1217 |
task_rlimit(p, RLIMIT_NPROC)) { |
b57922b6c fork: reorder per... |
1218 1219 |
if (p->real_cred->user != INIT_USER && !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) |
1da177e4c Linux-2.6.12-rc2 |
1220 1221 |
goto bad_fork_free; } |
72fa59970 move RLIMIT_NPROC... |
1222 |
current->flags &= ~PF_NPROC_EXCEEDED; |
1da177e4c Linux-2.6.12-rc2 |
1223 |
|
f1752eec6 CRED: Detach the ... |
1224 1225 1226 |
retval = copy_creds(p, clone_flags); if (retval < 0) goto bad_fork_free; |
1da177e4c Linux-2.6.12-rc2 |
1227 1228 1229 1230 1231 1232 |
/* * If multiple threads are within copy_process(), then this check * triggers too late. This doesn't hurt, the check is only there * to stop root fork bombs. */ |
04ec93fe9 fork.c: fix NULL ... |
1233 |
retval = -EAGAIN; |
1da177e4c Linux-2.6.12-rc2 |
1234 1235 |
if (nr_threads >= max_threads) goto bad_fork_cleanup_count; |
ca74e92b4 [PATCH] per-task-... |
1236 |
delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ |
514ddb446 fork: collapse co... |
1237 1238 |
p->flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER); p->flags |= PF_FORKNOEXEC; |
1da177e4c Linux-2.6.12-rc2 |
1239 1240 |
INIT_LIST_HEAD(&p->children); INIT_LIST_HEAD(&p->sibling); |
f41d911f8 rcu: Merge preemp... |
1241 |
rcu_copy_process(p); |
1da177e4c Linux-2.6.12-rc2 |
1242 1243 |
p->vfork_done = NULL; spin_lock_init(&p->alloc_lock); |
1da177e4c Linux-2.6.12-rc2 |
1244 |
|
1da177e4c Linux-2.6.12-rc2 |
1245 |
init_sigpending(&p->pending); |
648616343 [S390] cputime: a... |
1246 1247 |
p->utime = p->stime = p->gtime = 0; p->utimescaled = p->stimescaled = 0; |
9fbc42eac cputime: Dynamica... |
1248 |
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
d37f761db cputime: Consolid... |
1249 |
p->prev_cputime.utime = p->prev_cputime.stime = 0; |
d99ca3b97 sched, cputime: C... |
1250 |
#endif |
6a61671bb cputime: Safely r... |
1251 1252 1253 1254 1255 |
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN seqlock_init(&p->vtime_seqlock); p->vtime_snap = 0; p->vtime_snap_whence = VTIME_SLEEPING; #endif |
a3a2e76c7 mm: avoid null-po... |
1256 1257 1258 |
#if defined(SPLIT_RSS_COUNTING) memset(&p->rss_stat, 0, sizeof(p->rss_stat)); #endif |
172ba844a sched: update del... |
1259 |
|
6976675d9 hrtimer: create a... |
1260 |
p->default_timer_slack_ns = current->timer_slack_ns; |
5995477ab task IO accountin... |
1261 |
task_io_accounting_init(&p->ioac); |
1da177e4c Linux-2.6.12-rc2 |
1262 |
acct_clear_integrals(p); |
f06febc96 timers: fix itime... |
1263 |
posix_cpu_timers_init(p); |
1da177e4c Linux-2.6.12-rc2 |
1264 |
|
ccbf62d8a sched: Make task-... |
1265 |
p->start_time = ktime_get_ns(); |
57e0be041 sched: Make task-... |
1266 |
p->real_start_time = ktime_get_boot_ns(); |
1da177e4c Linux-2.6.12-rc2 |
1267 |
p->io_context = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1268 |
p->audit_context = NULL; |
4714d1d32 cgroups: read-wri... |
1269 |
if (clone_flags & CLONE_THREAD) |
257058ae2 threadgroup: rena... |
1270 |
threadgroup_change_begin(current); |
b4f48b636 Task Control Grou... |
1271 |
cgroup_fork(p); |
1da177e4c Linux-2.6.12-rc2 |
1272 |
#ifdef CONFIG_NUMA |
846a16bf0 mempolicy: rename... |
1273 |
p->mempolicy = mpol_dup(p->mempolicy); |
fb0a685cb kernel/fork.c: fi... |
1274 1275 1276 |
if (IS_ERR(p->mempolicy)) { retval = PTR_ERR(p->mempolicy); p->mempolicy = NULL; |
e8604cb43 cgroup: fix spuri... |
1277 |
goto bad_fork_cleanup_threadgroup_lock; |
fb0a685cb kernel/fork.c: fi... |
1278 |
} |
1da177e4c Linux-2.6.12-rc2 |
1279 |
#endif |
778d3b0ff cpusets: randomiz... |
1280 1281 1282 |
#ifdef CONFIG_CPUSETS p->cpuset_mem_spread_rotor = NUMA_NO_NODE; p->cpuset_slab_spread_rotor = NUMA_NO_NODE; |
cc9a6c877 cpuset: mm: reduc... |
1283 |
seqcount_init(&p->mems_allowed_seq); |
778d3b0ff cpusets: randomiz... |
1284 |
#endif |
de30a2b35 [PATCH] lockdep: ... |
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 |
#ifdef CONFIG_TRACE_IRQFLAGS p->irq_events = 0; p->hardirqs_enabled = 0; p->hardirq_enable_ip = 0; p->hardirq_enable_event = 0; p->hardirq_disable_ip = _THIS_IP_; p->hardirq_disable_event = 0; p->softirqs_enabled = 1; p->softirq_enable_ip = _THIS_IP_; p->softirq_enable_event = 0; p->softirq_disable_ip = 0; p->softirq_disable_event = 0; p->hardirq_context = 0; p->softirq_context = 0; #endif |
fbb9ce953 [PATCH] lockdep: ... |
1300 1301 1302 1303 1304 |
#ifdef CONFIG_LOCKDEP p->lockdep_depth = 0; /* no locks held yet */ p->curr_chain_key = 0; p->lockdep_recursion = 0; #endif |
1da177e4c Linux-2.6.12-rc2 |
1305 |
|
408894ee4 [PATCH] mutex sub... |
1306 1307 1308 |
#ifdef CONFIG_DEBUG_MUTEXES p->blocked_on = NULL; /* not blocked yet */ #endif |
cafe56359 bcache: A block l... |
1309 1310 1311 1312 |
#ifdef CONFIG_BCACHE p->sequential_io = 0; p->sequential_io_avg = 0; #endif |
0f4814065 x86, ptrace: add ... |
1313 |
|
3c90e6e99 sched: fix copy_n... |
1314 |
/* Perform scheduler related setup. Assign this task to a CPU. */ |
aab03e05e sched/deadline: A... |
1315 1316 1317 |
retval = sched_fork(clone_flags, p); if (retval) goto bad_fork_cleanup_policy; |
6ab423e0e perf_counter: Pro... |
1318 |
|
cdd6c482c perf: Do the big ... |
1319 |
retval = perf_event_init_task(p); |
6ab423e0e perf_counter: Pro... |
1320 1321 |
if (retval) goto bad_fork_cleanup_policy; |
fb0a685cb kernel/fork.c: fi... |
1322 1323 |
retval = audit_alloc(p); if (retval) |
6c72e3501 perf: fix perf bu... |
1324 |
goto bad_fork_cleanup_perf; |
1da177e4c Linux-2.6.12-rc2 |
1325 |
/* copy all the process information */ |
ab602f799 shm: make exit_sh... |
1326 |
shm_init_task(p); |
fb0a685cb kernel/fork.c: fi... |
1327 1328 |
retval = copy_semundo(clone_flags, p); if (retval) |
1da177e4c Linux-2.6.12-rc2 |
1329 |
goto bad_fork_cleanup_audit; |
fb0a685cb kernel/fork.c: fi... |
1330 1331 |
retval = copy_files(clone_flags, p); if (retval) |
1da177e4c Linux-2.6.12-rc2 |
1332 |
goto bad_fork_cleanup_semundo; |
fb0a685cb kernel/fork.c: fi... |
1333 1334 |
retval = copy_fs(clone_flags, p); if (retval) |
1da177e4c Linux-2.6.12-rc2 |
1335 |
goto bad_fork_cleanup_files; |
fb0a685cb kernel/fork.c: fi... |
1336 1337 |
retval = copy_sighand(clone_flags, p); if (retval) |
1da177e4c Linux-2.6.12-rc2 |
1338 |
goto bad_fork_cleanup_fs; |
fb0a685cb kernel/fork.c: fi... |
1339 1340 |
retval = copy_signal(clone_flags, p); if (retval) |
1da177e4c Linux-2.6.12-rc2 |
1341 |
goto bad_fork_cleanup_sighand; |
fb0a685cb kernel/fork.c: fi... |
1342 1343 |
retval = copy_mm(clone_flags, p); if (retval) |
1da177e4c Linux-2.6.12-rc2 |
1344 |
goto bad_fork_cleanup_signal; |
fb0a685cb kernel/fork.c: fi... |
1345 1346 |
retval = copy_namespaces(clone_flags, p); if (retval) |
d84f4f992 CRED: Inaugurate ... |
1347 |
goto bad_fork_cleanup_mm; |
fb0a685cb kernel/fork.c: fi... |
1348 1349 |
retval = copy_io(clone_flags, p); if (retval) |
fd0928df9 ioprio: move io p... |
1350 |
goto bad_fork_cleanup_namespaces; |
afa86fc42 flagday: don't pa... |
1351 |
retval = copy_thread(clone_flags, stack_start, stack_size, p); |
1da177e4c Linux-2.6.12-rc2 |
1352 |
if (retval) |
fd0928df9 ioprio: move io p... |
1353 |
goto bad_fork_cleanup_io; |
1da177e4c Linux-2.6.12-rc2 |
1354 |
|
425fb2b4b pid namespaces: m... |
1355 |
if (pid != &init_struct_pid) { |
c2b1df2eb Rename nsproxy.pi... |
1356 |
pid = alloc_pid(p->nsproxy->pid_ns_for_children); |
35f71bc0a fork: report pid ... |
1357 1358 |
if (IS_ERR(pid)) { retval = PTR_ERR(pid); |
fd0928df9 ioprio: move io p... |
1359 |
goto bad_fork_cleanup_io; |
35f71bc0a fork: report pid ... |
1360 |
} |
425fb2b4b pid namespaces: m... |
1361 |
} |
1da177e4c Linux-2.6.12-rc2 |
1362 1363 1364 1365 |
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; /* * Clear TID on mm_release()? */ |
fb0a685cb kernel/fork.c: fi... |
1366 |
p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr : NULL; |
73c101011 block: initial pa... |
1367 1368 1369 |
#ifdef CONFIG_BLOCK p->plug = NULL; #endif |
42b2dd0a0 Shrink task_struc... |
1370 |
#ifdef CONFIG_FUTEX |
8f17d3a50 [PATCH] lightweig... |
1371 1372 1373 1374 |
p->robust_list = NULL; #ifdef CONFIG_COMPAT p->compat_robust_list = NULL; #endif |
c87e2837b [PATCH] pi-futex:... |
1375 1376 |
INIT_LIST_HEAD(&p->pi_state_list); p->pi_state_cache = NULL; |
42b2dd0a0 Shrink task_struc... |
1377 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
1378 |
/* |
f9a3879ab [PATCH] Fix sigal... |
1379 1380 1381 1382 1383 1384 |
* sigaltstack should be cleared when sharing the same VM */ if ((clone_flags & (CLONE_VM|CLONE_VFORK)) == CLONE_VM) p->sas_ss_sp = p->sas_ss_size = 0; /* |
6580807da ptrace: copy_proc... |
1385 1386 |
* Syscall tracing and stepping should be turned off in the * child regardless of CLONE_PTRACE. |
1da177e4c Linux-2.6.12-rc2 |
1387 |
*/ |
6580807da ptrace: copy_proc... |
1388 |
user_disable_single_step(p); |
1da177e4c Linux-2.6.12-rc2 |
1389 |
clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); |
ed75e8d58 [PATCH] UML Suppo... |
1390 1391 1392 |
#ifdef TIF_SYSCALL_EMU clear_tsk_thread_flag(p, TIF_SYSCALL_EMU); #endif |
9745512ce sched: latencytop... |
1393 |
clear_all_latency_tracing(p); |
1da177e4c Linux-2.6.12-rc2 |
1394 |
|
1da177e4c Linux-2.6.12-rc2 |
1395 |
/* ok, now we should be set up.. */ |
18c830df7 kernel/fork.c:cop... |
1396 1397 |
p->pid = pid_nr(pid); if (clone_flags & CLONE_THREAD) { |
5f8aadd8b CLONE_PARENT shou... |
1398 |
p->exit_signal = -1; |
18c830df7 kernel/fork.c:cop... |
1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 |
p->group_leader = current->group_leader; p->tgid = current->tgid; } else { if (clone_flags & CLONE_PARENT) p->exit_signal = current->group_leader->exit_signal; else p->exit_signal = (clone_flags & CSIGNAL); p->group_leader = p; p->tgid = p->pid; } |
5f8aadd8b CLONE_PARENT shou... |
1409 |
|
9d823e8f6 writeback: per ta... |
1410 1411 |
p->nr_dirtied = 0; p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10); |
83712358b writeback: dirty ... |
1412 |
p->dirty_paused_when = 0; |
9d823e8f6 writeback: per ta... |
1413 |
|
bb8cbbfee tasks/fork: Remov... |
1414 |
p->pdeath_signal = 0; |
47e65328a [PATCH] pids: kil... |
1415 |
INIT_LIST_HEAD(&p->thread_group); |
158e1645e trim task_work: g... |
1416 |
p->task_works = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1417 |
|
18c830df7 kernel/fork.c:cop... |
1418 1419 1420 1421 |
/* * Make it visible to the rest of the system, but dont wake it up yet. * Need tasklist lock for parent etc handling! */ |
1da177e4c Linux-2.6.12-rc2 |
1422 |
write_lock_irq(&tasklist_lock); |
1da177e4c Linux-2.6.12-rc2 |
1423 |
/* CLONE_PARENT re-uses the old parent */ |
2d5516cbb copy_process: fix... |
1424 |
if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { |
1da177e4c Linux-2.6.12-rc2 |
1425 |
p->real_parent = current->real_parent; |
2d5516cbb copy_process: fix... |
1426 1427 |
p->parent_exec_id = current->parent_exec_id; } else { |
1da177e4c Linux-2.6.12-rc2 |
1428 |
p->real_parent = current; |
2d5516cbb copy_process: fix... |
1429 1430 |
p->parent_exec_id = current->self_exec_id; } |
1da177e4c Linux-2.6.12-rc2 |
1431 |
|
3f17da699 [PATCH] fix kill_... |
1432 |
spin_lock(¤t->sighand->siglock); |
4a2c7a783 [PATCH] make fork... |
1433 1434 |
/* |
dbd952127 seccomp: introduc... |
1435 1436 1437 1438 1439 1440 |
* Copy seccomp details explicitly here, in case they were changed * before holding sighand lock. */ copy_seccomp(p); /* |
4a2c7a783 [PATCH] make fork... |
1441 1442 1443 1444 1445 1446 |
* Process group and session signals need to be delivered to just the * parent before the fork or both the parent and the child after the * fork. Restart if a signal comes in before we add the new process to * it's process group. * A fatal signal pending means that current will exit, so the new * thread can't slip out of an OOM kill (or normal SIGKILL). |
fb0a685cb kernel/fork.c: fi... |
1447 |
*/ |
23ff44402 whitespace fixes:... |
1448 |
recalc_sigpending(); |
4a2c7a783 [PATCH] make fork... |
1449 1450 1451 1452 |
if (signal_pending(current)) { spin_unlock(¤t->sighand->siglock); write_unlock_irq(&tasklist_lock); retval = -ERESTARTNOINTR; |
f7e8b616e function-graph: m... |
1453 |
goto bad_fork_free_pid; |
4a2c7a783 [PATCH] make fork... |
1454 |
} |
73b9ebfe1 [PATCH] pidhash: ... |
1455 |
if (likely(p->pid)) { |
4b9d33e6d ptrace: kill clon... |
1456 |
ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace); |
73b9ebfe1 [PATCH] pidhash: ... |
1457 |
|
819077398 kernel/fork.c:cop... |
1458 |
init_task_pid(p, PIDTYPE_PID, pid); |
73b9ebfe1 [PATCH] pidhash: ... |
1459 |
if (thread_group_leader(p)) { |
819077398 kernel/fork.c:cop... |
1460 1461 |
init_task_pid(p, PIDTYPE_PGID, task_pgrp(current)); init_task_pid(p, PIDTYPE_SID, task_session(current)); |
1c4042c29 pidns: Consolidat... |
1462 |
if (is_child_reaper(pid)) { |
17cf22c33 pidns: Use task_a... |
1463 |
ns_of_pid(pid)->child_reaper = p; |
1c4042c29 pidns: Consolidat... |
1464 1465 |
p->signal->flags |= SIGNAL_UNKILLABLE; } |
73b9ebfe1 [PATCH] pidhash: ... |
1466 |
|
fea9d1755 ITIMER_REAL: conv... |
1467 |
p->signal->leader_pid = pid; |
9c9f4ded9 tty: Add a kref c... |
1468 |
p->signal->tty = tty_kref_get(current->signal->tty); |
9cd80bbb0 do_wait() optimiz... |
1469 |
list_add_tail(&p->sibling, &p->real_parent->children); |
5e85d4abe [PATCH] task: Mak... |
1470 |
list_add_tail_rcu(&p->tasks, &init_task.tasks); |
819077398 kernel/fork.c:cop... |
1471 1472 |
attach_pid(p, PIDTYPE_PGID); attach_pid(p, PIDTYPE_SID); |
909ea9646 core: Replace __g... |
1473 |
__this_cpu_inc(process_counts); |
80628ca06 kernel/fork.c:cop... |
1474 1475 1476 1477 |
} else { current->signal->nr_threads++; atomic_inc(¤t->signal->live); atomic_inc(¤t->signal->sigcnt); |
80628ca06 kernel/fork.c:cop... |
1478 1479 |
list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); |
0c740d0af introduce for_eac... |
1480 1481 |
list_add_tail_rcu(&p->thread_node, &p->signal->thread_head); |
73b9ebfe1 [PATCH] pidhash: ... |
1482 |
} |
819077398 kernel/fork.c:cop... |
1483 |
attach_pid(p, PIDTYPE_PID); |
73b9ebfe1 [PATCH] pidhash: ... |
1484 |
nr_threads++; |
1da177e4c Linux-2.6.12-rc2 |
1485 |
} |
1da177e4c Linux-2.6.12-rc2 |
1486 |
total_forks++; |
3f17da699 [PATCH] fix kill_... |
1487 |
spin_unlock(¤t->sighand->siglock); |
4af4206be tracing: Fix sysc... |
1488 |
syscall_tracepoint_update(p); |
1da177e4c Linux-2.6.12-rc2 |
1489 |
write_unlock_irq(&tasklist_lock); |
4af4206be tracing: Fix sysc... |
1490 |
|
c13cf856c [PATCH] fork.c: p... |
1491 |
proc_fork_connector(p); |
817929ec2 Task Control Grou... |
1492 |
cgroup_post_fork(p); |
4714d1d32 cgroups: read-wri... |
1493 |
if (clone_flags & CLONE_THREAD) |
257058ae2 threadgroup: rena... |
1494 |
threadgroup_change_end(current); |
cdd6c482c perf: Do the big ... |
1495 |
perf_event_fork(p); |
43d2b1132 tracepoint: add t... |
1496 1497 |
trace_task_newtask(p, clone_flags); |
3ab679661 uprobes: Teach up... |
1498 |
uprobe_copy_process(p, clone_flags); |
43d2b1132 tracepoint: add t... |
1499 |
|
1da177e4c Linux-2.6.12-rc2 |
1500 |
return p; |
425fb2b4b pid namespaces: m... |
1501 1502 1503 |
bad_fork_free_pid: if (pid != &init_struct_pid) free_pid(pid); |
fd0928df9 ioprio: move io p... |
1504 |
bad_fork_cleanup_io: |
b69f22920 block: Fix io_con... |
1505 1506 |
if (p->io_context) exit_io_context(p); |
ab516013a [PATCH] namespace... |
1507 |
bad_fork_cleanup_namespaces: |
444f378b2 Revert "[PATCH] n... |
1508 |
exit_task_namespaces(p); |
1da177e4c Linux-2.6.12-rc2 |
1509 |
bad_fork_cleanup_mm: |
c9f01245b oom: remove oom_d... |
1510 |
if (p->mm) |
1da177e4c Linux-2.6.12-rc2 |
1511 1512 |
mmput(p->mm); bad_fork_cleanup_signal: |
4ab6c0833 clone(): fix race... |
1513 |
if (!(clone_flags & CLONE_THREAD)) |
1c5354de9 sched: Move sched... |
1514 |
free_signal_struct(p->signal); |
1da177e4c Linux-2.6.12-rc2 |
1515 |
bad_fork_cleanup_sighand: |
a7e5328a0 [PATCH] cleanup _... |
1516 |
__cleanup_sighand(p->sighand); |
1da177e4c Linux-2.6.12-rc2 |
1517 1518 1519 1520 1521 1522 1523 1524 |
bad_fork_cleanup_fs: exit_fs(p); /* blocking */ bad_fork_cleanup_files: exit_files(p); /* blocking */ bad_fork_cleanup_semundo: exit_sem(p); bad_fork_cleanup_audit: audit_free(p); |
6c72e3501 perf: fix perf bu... |
1525 |
bad_fork_cleanup_perf: |
cdd6c482c perf: Do the big ... |
1526 |
perf_event_free_task(p); |
6c72e3501 perf: fix perf bu... |
1527 |
bad_fork_cleanup_policy: |
1da177e4c Linux-2.6.12-rc2 |
1528 |
#ifdef CONFIG_NUMA |
f0be3d32b mempolicy: rename... |
1529 |
mpol_put(p->mempolicy); |
e8604cb43 cgroup: fix spuri... |
1530 |
bad_fork_cleanup_threadgroup_lock: |
1da177e4c Linux-2.6.12-rc2 |
1531 |
#endif |
4714d1d32 cgroups: read-wri... |
1532 |
if (clone_flags & CLONE_THREAD) |
257058ae2 threadgroup: rena... |
1533 |
threadgroup_change_end(current); |
35df17c57 [PATCH] task dela... |
1534 |
delayacct_tsk_free(p); |
1da177e4c Linux-2.6.12-rc2 |
1535 |
bad_fork_cleanup_count: |
d84f4f992 CRED: Inaugurate ... |
1536 |
atomic_dec(&p->cred->user->processes); |
e0e817392 CRED: Add some co... |
1537 |
exit_creds(p); |
1da177e4c Linux-2.6.12-rc2 |
1538 1539 |
bad_fork_free: free_task(p); |
fe7d37d1f [PATCH] copy_proc... |
1540 1541 |
fork_out: return ERR_PTR(retval); |
1da177e4c Linux-2.6.12-rc2 |
1542 |
} |
f106eee10 pids: fix fork_id... |
1543 1544 1545 1546 1547 1548 1549 1550 1551 |
static inline void init_idle_pids(struct pid_link *links) { enum pid_type type; for (type = PIDTYPE_PID; type < PIDTYPE_MAX; ++type) { INIT_HLIST_NODE(&links[type].node); /* not really needed */ links[type].pid = &init_struct_pid; } } |
0db0628d9 kernel: delete __... |
1552 |
struct task_struct *fork_idle(int cpu) |
1da177e4c Linux-2.6.12-rc2 |
1553 |
{ |
36c8b5868 [PATCH] sched: cl... |
1554 |
struct task_struct *task; |
62e791c1b don't pass regs t... |
1555 |
task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0); |
f106eee10 pids: fix fork_id... |
1556 1557 |
if (!IS_ERR(task)) { init_idle_pids(task->pids); |
753ca4f31 [PATCH] fix copy_... |
1558 |
init_idle(task, cpu); |
f106eee10 pids: fix fork_id... |
1559 |
} |
73b9ebfe1 [PATCH] pidhash: ... |
1560 |
|
1da177e4c Linux-2.6.12-rc2 |
1561 1562 |
return task; } |
1da177e4c Linux-2.6.12-rc2 |
1563 1564 1565 1566 1567 1568 1569 1570 |
/* * Ok, this is the main fork-routine. * * It copies the process, and if successful kick-starts * it and waits for it to finish using the VM if required. */ long do_fork(unsigned long clone_flags, unsigned long stack_start, |
1da177e4c Linux-2.6.12-rc2 |
1571 1572 1573 1574 1575 1576 |
unsigned long stack_size, int __user *parent_tidptr, int __user *child_tidptr) { struct task_struct *p; int trace = 0; |
92476d7fc [PATCH] pidhash: ... |
1577 |
long nr; |
1da177e4c Linux-2.6.12-rc2 |
1578 |
|
bdff746a3 clone: prepare to... |
1579 |
/* |
4b9d33e6d ptrace: kill clon... |
1580 1581 1582 1583 |
* Determine whether and which event to report to ptracer. When * called from kernel_thread or CLONE_UNTRACED is explicitly * requested, no event is reported; otherwise, report if the event * for the type of forking is enabled. |
09a05394f tracehook: clone |
1584 |
*/ |
e80d6661c flagday: kill pt_... |
1585 |
if (!(clone_flags & CLONE_UNTRACED)) { |
4b9d33e6d ptrace: kill clon... |
1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 |
if (clone_flags & CLONE_VFORK) trace = PTRACE_EVENT_VFORK; else if ((clone_flags & CSIGNAL) != SIGCHLD) trace = PTRACE_EVENT_CLONE; else trace = PTRACE_EVENT_FORK; if (likely(!ptrace_event_enabled(current, trace))) trace = 0; } |
1da177e4c Linux-2.6.12-rc2 |
1596 |
|
62e791c1b don't pass regs t... |
1597 |
p = copy_process(clone_flags, stack_start, stack_size, |
09a05394f tracehook: clone |
1598 |
child_tidptr, NULL, trace); |
1da177e4c Linux-2.6.12-rc2 |
1599 1600 1601 1602 1603 1604 |
/* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. */ if (!IS_ERR(p)) { struct completion vfork; |
4e52365f2 ptrace: fix fork ... |
1605 |
struct pid *pid; |
1da177e4c Linux-2.6.12-rc2 |
1606 |
|
0a16b6075 tracing, sched: L... |
1607 |
trace_sched_process_fork(current, p); |
4e52365f2 ptrace: fix fork ... |
1608 1609 |
pid = get_task_pid(p, PIDTYPE_PID); nr = pid_vnr(pid); |
30e49c263 pid namespaces: a... |
1610 1611 1612 |
if (clone_flags & CLONE_PARENT_SETTID) put_user(nr, parent_tidptr); |
a6f5e0637 pid namespaces: m... |
1613 |
|
1da177e4c Linux-2.6.12-rc2 |
1614 1615 1616 |
if (clone_flags & CLONE_VFORK) { p->vfork_done = &vfork; init_completion(&vfork); |
d68b46fe1 vfork: make it ki... |
1617 |
get_task_struct(p); |
1da177e4c Linux-2.6.12-rc2 |
1618 |
} |
3e51e3edf sched: Remove unu... |
1619 |
wake_up_new_task(p); |
1da177e4c Linux-2.6.12-rc2 |
1620 |
|
4b9d33e6d ptrace: kill clon... |
1621 1622 |
/* forking complete and child started to run, tell ptracer */ if (unlikely(trace)) |
4e52365f2 ptrace: fix fork ... |
1623 |
ptrace_event_pid(trace, pid); |
09a05394f tracehook: clone |
1624 |
|
1da177e4c Linux-2.6.12-rc2 |
1625 |
if (clone_flags & CLONE_VFORK) { |
d68b46fe1 vfork: make it ki... |
1626 |
if (!wait_for_vfork_done(p, &vfork)) |
4e52365f2 ptrace: fix fork ... |
1627 |
ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid); |
1da177e4c Linux-2.6.12-rc2 |
1628 |
} |
4e52365f2 ptrace: fix fork ... |
1629 1630 |
put_pid(pid); |
1da177e4c Linux-2.6.12-rc2 |
1631 |
} else { |
92476d7fc [PATCH] pidhash: ... |
1632 |
nr = PTR_ERR(p); |
1da177e4c Linux-2.6.12-rc2 |
1633 |
} |
92476d7fc [PATCH] pidhash: ... |
1634 |
return nr; |
1da177e4c Linux-2.6.12-rc2 |
1635 |
} |
2aa3a7f86 preparation for g... |
1636 1637 1638 1639 1640 |
/* * Create a kernel thread. */ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { |
e80d6661c flagday: kill pt_... |
1641 |
return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, |
2aa3a7f86 preparation for g... |
1642 1643 |
(unsigned long)arg, NULL, NULL); } |
2aa3a7f86 preparation for g... |
1644 |
|
d2125043a generic sys_fork ... |
1645 1646 1647 1648 |
#ifdef __ARCH_WANT_SYS_FORK SYSCALL_DEFINE0(fork) { #ifdef CONFIG_MMU |
e80d6661c flagday: kill pt_... |
1649 |
return do_fork(SIGCHLD, 0, 0, NULL, NULL); |
d2125043a generic sys_fork ... |
1650 1651 |
#else /* can not support in nommu mode */ |
5d59e1827 kernel/fork.c: fi... |
1652 |
return -EINVAL; |
d2125043a generic sys_fork ... |
1653 1654 1655 1656 1657 1658 1659 |
#endif } #endif #ifdef __ARCH_WANT_SYS_VFORK SYSCALL_DEFINE0(vfork) { |
5d59e1827 kernel/fork.c: fi... |
1660 |
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, |
d2125043a generic sys_fork ... |
1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 |
0, NULL, NULL); } #endif #ifdef __ARCH_WANT_SYS_CLONE #ifdef CONFIG_CLONE_BACKWARDS SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, int __user *, parent_tidptr, int, tls_val, int __user *, child_tidptr) #elif defined(CONFIG_CLONE_BACKWARDS2) SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val) |
dfa9771a7 microblaze: fix c... |
1676 1677 1678 1679 1680 1681 |
#elif defined(CONFIG_CLONE_BACKWARDS3) SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp, int, stack_size, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val) |
d2125043a generic sys_fork ... |
1682 1683 1684 1685 1686 1687 1688 |
#else SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val) #endif { |
2cf096668 make SYSCALL_DEFI... |
1689 |
return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr); |
d2125043a generic sys_fork ... |
1690 1691 |
} #endif |
5fd63b308 [PATCH] x86_64: I... |
1692 1693 1694 |
#ifndef ARCH_MIN_MMSTRUCT_ALIGN #define ARCH_MIN_MMSTRUCT_ALIGN 0 #endif |
51cc50685 SL*B: drop kmem c... |
1695 |
static void sighand_ctor(void *data) |
aa1757f90 [PATCH] convert s... |
1696 1697 |
{ struct sighand_struct *sighand = data; |
a35afb830 Remove SLAB_CTOR_... |
1698 |
spin_lock_init(&sighand->siglock); |
b8fceee17 signalfd simplifi... |
1699 |
init_waitqueue_head(&sighand->signalfd_wqh); |
aa1757f90 [PATCH] convert s... |
1700 |
} |
1da177e4c Linux-2.6.12-rc2 |
1701 1702 1703 1704 |
void __init proc_caches_init(void) { sighand_cachep = kmem_cache_create("sighand_cache", sizeof(struct sighand_struct), 0, |
2dff44052 kmemcheck: add mm... |
1705 1706 |
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU| SLAB_NOTRACK, sighand_ctor); |
1da177e4c Linux-2.6.12-rc2 |
1707 1708 |
signal_cachep = kmem_cache_create("signal_cache", sizeof(struct signal_struct), 0, |
2dff44052 kmemcheck: add mm... |
1709 |
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
20c2df83d mm: Remove slab d... |
1710 |
files_cachep = kmem_cache_create("files_cache", |
1da177e4c Linux-2.6.12-rc2 |
1711 |
sizeof(struct files_struct), 0, |
2dff44052 kmemcheck: add mm... |
1712 |
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
20c2df83d mm: Remove slab d... |
1713 |
fs_cachep = kmem_cache_create("fs_cache", |
1da177e4c Linux-2.6.12-rc2 |
1714 |
sizeof(struct fs_struct), 0, |
2dff44052 kmemcheck: add mm... |
1715 |
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
6345d24da mm: Fix boot cras... |
1716 1717 1718 1719 1720 1721 1722 |
/* * FIXME! The "sizeof(struct mm_struct)" currently includes the * whole struct cpumask for the OFFSTACK case. We could change * this to *only* allocate as much of it as required by the * maximum number of CPU's we can ever have. The cpumask_allocation * is at the end of the structure, exactly for that reason. */ |
1da177e4c Linux-2.6.12-rc2 |
1723 |
mm_cachep = kmem_cache_create("mm_struct", |
5fd63b308 [PATCH] x86_64: I... |
1724 |
sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, |
2dff44052 kmemcheck: add mm... |
1725 |
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
33e5d7697 nommu: fix a numb... |
1726 |
vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC); |
8feae1311 NOMMU: Make VMAs ... |
1727 |
mmap_init(); |
665771939 make sure that ns... |
1728 |
nsproxy_cache_init(); |
1da177e4c Linux-2.6.12-rc2 |
1729 |
} |
cf2e340f4 [PATCH] unshare s... |
1730 |
|
cf2e340f4 [PATCH] unshare s... |
1731 |
/* |
9bfb23fc4 sys_unshare: remo... |
1732 |
* Check constraints on flags passed to the unshare system call. |
cf2e340f4 [PATCH] unshare s... |
1733 |
*/ |
9bfb23fc4 sys_unshare: remo... |
1734 |
static int check_unshare_flags(unsigned long unshare_flags) |
cf2e340f4 [PATCH] unshare s... |
1735 |
{ |
9bfb23fc4 sys_unshare: remo... |
1736 1737 |
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| |
50804fe37 pidns: Support un... |
1738 |
CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET| |
b2e0d9870 userns: Implement... |
1739 |
CLONE_NEWUSER|CLONE_NEWPID)) |
9bfb23fc4 sys_unshare: remo... |
1740 |
return -EINVAL; |
cf2e340f4 [PATCH] unshare s... |
1741 |
/* |
11e43d237 unshare: Unsharin... |
1742 1743 1744 1745 |
* Not implemented, but pretend it works if there is nothing * to unshare. Note that unsharing the address space or the * signal handlers also need to unshare the signal queues (aka * CLONE_THREAD). |
cf2e340f4 [PATCH] unshare s... |
1746 |
*/ |
9bfb23fc4 sys_unshare: remo... |
1747 |
if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) { |
11e43d237 unshare: Unsharin... |
1748 1749 1750 1751 1752 1753 1754 1755 1756 |
if (!thread_group_empty(current)) return -EINVAL; } if (unshare_flags & (CLONE_SIGHAND | CLONE_VM)) { if (atomic_read(¤t->sighand->count) > 1) return -EINVAL; } if (unshare_flags & CLONE_VM) { if (!current_is_single_threaded()) |
9bfb23fc4 sys_unshare: remo... |
1757 1758 |
return -EINVAL; } |
cf2e340f4 [PATCH] unshare s... |
1759 1760 1761 1762 1763 |
return 0; } /* |
99d1419d9 [PATCH] unshare s... |
1764 |
* Unshare the filesystem structure if it is being shared |
cf2e340f4 [PATCH] unshare s... |
1765 1766 1767 1768 |
*/ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp) { struct fs_struct *fs = current->fs; |
498052bba New locking/refco... |
1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 |
if (!(unshare_flags & CLONE_FS) || !fs) return 0; /* don't need lock here; in the worst case we'll do useless copy */ if (fs->users == 1) return 0; *new_fsp = copy_fs_struct(fs); if (!*new_fsp) return -ENOMEM; |
cf2e340f4 [PATCH] unshare s... |
1779 1780 1781 1782 1783 |
return 0; } /* |
a016f3389 [PATCH] unshare s... |
1784 |
* Unshare file descriptor table if it is being shared |
cf2e340f4 [PATCH] unshare s... |
1785 1786 1787 1788 |
*/ static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp) { struct files_struct *fd = current->files; |
a016f3389 [PATCH] unshare s... |
1789 |
int error = 0; |
cf2e340f4 [PATCH] unshare s... |
1790 1791 |
if ((unshare_flags & CLONE_FILES) && |
a016f3389 [PATCH] unshare s... |
1792 1793 1794 1795 1796 |
(fd && atomic_read(&fd->count) > 1)) { *new_fdp = dup_fd(fd, &error); if (!*new_fdp) return error; } |
cf2e340f4 [PATCH] unshare s... |
1797 1798 1799 1800 1801 |
return 0; } /* |
cf2e340f4 [PATCH] unshare s... |
1802 1803 1804 1805 1806 1807 1808 |
* unshare allows a process to 'unshare' part of the process * context which was originally shared using clone. copy_* * functions used by do_fork() cannot be used here directly * because they modify an inactive task_struct that is being * constructed. Here we are modifying the current, active, * task_struct. */ |
6559eed8c [CVE-2009-0029] S... |
1809 |
SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) |
cf2e340f4 [PATCH] unshare s... |
1810 |
{ |
cf2e340f4 [PATCH] unshare s... |
1811 |
struct fs_struct *fs, *new_fs = NULL; |
cf2e340f4 [PATCH] unshare s... |
1812 |
struct files_struct *fd, *new_fd = NULL; |
b2e0d9870 userns: Implement... |
1813 |
struct cred *new_cred = NULL; |
cf7b708c8 Make access to ta... |
1814 |
struct nsproxy *new_nsproxy = NULL; |
9edff4ab1 ipc: sysvsem: imp... |
1815 |
int do_sysvsem = 0; |
9bfb23fc4 sys_unshare: remo... |
1816 |
int err; |
cf2e340f4 [PATCH] unshare s... |
1817 |
|
50804fe37 pidns: Support un... |
1818 |
/* |
b2e0d9870 userns: Implement... |
1819 1820 1821 |
* If unsharing a user namespace must also unshare the thread. */ if (unshare_flags & CLONE_NEWUSER) |
e66eded83 userns: Don't all... |
1822 |
unshare_flags |= CLONE_THREAD | CLONE_FS; |
b2e0d9870 userns: Implement... |
1823 |
/* |
50804fe37 pidns: Support un... |
1824 1825 1826 1827 |
* If unsharing vm, must also unshare signal handlers. */ if (unshare_flags & CLONE_VM) unshare_flags |= CLONE_SIGHAND; |
6013f67fc ipc: sysvsem: for... |
1828 |
/* |
11e43d237 unshare: Unsharin... |
1829 1830 1831 1832 1833 |
* If unsharing a signal handlers, must also unshare the signal queues. */ if (unshare_flags & CLONE_SIGHAND) unshare_flags |= CLONE_THREAD; /* |
9bfb23fc4 sys_unshare: remo... |
1834 1835 1836 1837 |
* If unsharing namespace, must also unshare filesystem information. */ if (unshare_flags & CLONE_NEWNS) unshare_flags |= CLONE_FS; |
50804fe37 pidns: Support un... |
1838 1839 1840 1841 |
err = check_unshare_flags(unshare_flags); if (err) goto bad_unshare_out; |
9bfb23fc4 sys_unshare: remo... |
1842 |
/* |
6013f67fc ipc: sysvsem: for... |
1843 1844 1845 1846 1847 |
* CLONE_NEWIPC must also detach from the undolist: after switching * to a new ipc namespace, the semaphore arrays from the old * namespace are unreachable. */ if (unshare_flags & (CLONE_NEWIPC|CLONE_SYSVSEM)) |
9edff4ab1 ipc: sysvsem: imp... |
1848 |
do_sysvsem = 1; |
fb0a685cb kernel/fork.c: fi... |
1849 1850 |
err = unshare_fs(unshare_flags, &new_fs); if (err) |
9bfb23fc4 sys_unshare: remo... |
1851 |
goto bad_unshare_out; |
fb0a685cb kernel/fork.c: fi... |
1852 1853 |
err = unshare_fd(unshare_flags, &new_fd); if (err) |
9bfb23fc4 sys_unshare: remo... |
1854 |
goto bad_unshare_cleanup_fs; |
b2e0d9870 userns: Implement... |
1855 |
err = unshare_userns(unshare_flags, &new_cred); |
fb0a685cb kernel/fork.c: fi... |
1856 |
if (err) |
9edff4ab1 ipc: sysvsem: imp... |
1857 |
goto bad_unshare_cleanup_fd; |
b2e0d9870 userns: Implement... |
1858 1859 1860 1861 |
err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy, new_cred, new_fs); if (err) goto bad_unshare_cleanup_cred; |
c0b2fc316 [PATCH] uts: copy... |
1862 |
|
b2e0d9870 userns: Implement... |
1863 |
if (new_fs || new_fd || do_sysvsem || new_cred || new_nsproxy) { |
9edff4ab1 ipc: sysvsem: imp... |
1864 1865 1866 1867 1868 1869 |
if (do_sysvsem) { /* * CLONE_SYSVSEM is equivalent to sys_exit(). */ exit_sem(current); } |
ab602f799 shm: make exit_sh... |
1870 1871 1872 1873 1874 |
if (unshare_flags & CLONE_NEWIPC) { /* Orphan segments in old ns (see sem above). */ exit_shm(current); shm_init_task(current); } |
ab516013a [PATCH] namespace... |
1875 |
|
6f977e6b2 fork: unshare: re... |
1876 |
if (new_nsproxy) |
cf7b708c8 Make access to ta... |
1877 |
switch_task_namespaces(current, new_nsproxy); |
cf2e340f4 [PATCH] unshare s... |
1878 |
|
cf7b708c8 Make access to ta... |
1879 |
task_lock(current); |
cf2e340f4 [PATCH] unshare s... |
1880 1881 |
if (new_fs) { fs = current->fs; |
2a4419b5b fs: fs_struct rwl... |
1882 |
spin_lock(&fs->lock); |
cf2e340f4 [PATCH] unshare s... |
1883 |
current->fs = new_fs; |
498052bba New locking/refco... |
1884 1885 1886 1887 |
if (--fs->users) new_fs = NULL; else new_fs = fs; |
2a4419b5b fs: fs_struct rwl... |
1888 |
spin_unlock(&fs->lock); |
cf2e340f4 [PATCH] unshare s... |
1889 |
} |
cf2e340f4 [PATCH] unshare s... |
1890 1891 1892 1893 1894 1895 1896 |
if (new_fd) { fd = current->files; current->files = new_fd; new_fd = fd; } task_unlock(current); |
b2e0d9870 userns: Implement... |
1897 1898 1899 1900 1901 1902 |
if (new_cred) { /* Install the new user namespace */ commit_creds(new_cred); new_cred = NULL; } |
cf2e340f4 [PATCH] unshare s... |
1903 |
} |
b2e0d9870 userns: Implement... |
1904 1905 1906 |
bad_unshare_cleanup_cred: if (new_cred) put_cred(new_cred); |
cf2e340f4 [PATCH] unshare s... |
1907 1908 1909 |
bad_unshare_cleanup_fd: if (new_fd) put_files_struct(new_fd); |
cf2e340f4 [PATCH] unshare s... |
1910 1911 |
bad_unshare_cleanup_fs: if (new_fs) |
498052bba New locking/refco... |
1912 |
free_fs_struct(new_fs); |
cf2e340f4 [PATCH] unshare s... |
1913 |
|
cf2e340f4 [PATCH] unshare s... |
1914 1915 1916 |
bad_unshare_out: return err; } |
3b1253880 [PATCH] sanitize ... |
1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 |
/* * Helper to unshare the files of the current task. * We don't want to expose copy_files internals to * the exec layer of the kernel. */ int unshare_files(struct files_struct **displaced) { struct task_struct *task = current; |
50704516f Fix uninitialized... |
1927 |
struct files_struct *copy = NULL; |
3b1253880 [PATCH] sanitize ... |
1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 |
int error; error = unshare_fd(CLONE_FILES, ©); if (error || !copy) { *displaced = NULL; return error; } *displaced = task->files; task_lock(task); task->files = copy; task_unlock(task); return 0; } |
16db3d3f1 kernel/sysctl.c: ... |
1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 |
int sysctl_max_threads(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table t; int ret; int threads = max_threads; int min = MIN_THREADS; int max = MAX_THREADS; t = *table; t.data = &threads; t.extra1 = &min; t.extra2 = &max; ret = proc_dointvec_minmax(&t, write, buffer, lenp, ppos); if (ret || !write) return ret; set_max_threads(threads); return 0; } |