diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 2cebfb23b0b8..51ad0b0b7266 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/ftrace.h> | 49 | #include <linux/ftrace.h> |
50 | #include <linux/profile.h> | 50 | #include <linux/profile.h> |
51 | #include <linux/rmap.h> | 51 | #include <linux/rmap.h> |
52 | #include <linux/ksm.h> | ||
52 | #include <linux/acct.h> | 53 | #include <linux/acct.h> |
53 | #include <linux/tsacct_kern.h> | 54 | #include <linux/tsacct_kern.h> |
54 | #include <linux/cn_proc.h> | 55 | #include <linux/cn_proc.h> |
@@ -62,6 +63,7 @@ | |||
62 | #include <linux/fs_struct.h> | 63 | #include <linux/fs_struct.h> |
63 | #include <linux/magic.h> | 64 | #include <linux/magic.h> |
64 | #include <linux/perf_event.h> | 65 | #include <linux/perf_event.h> |
66 | #include <linux/posix-timers.h> | ||
65 | 67 | ||
66 | #include <asm/pgtable.h> | 68 | #include <asm/pgtable.h> |
67 | #include <asm/pgalloc.h> | 69 | #include <asm/pgalloc.h> |
@@ -136,9 +138,17 @@ struct kmem_cache *vm_area_cachep; | |||
136 | /* SLAB cache for mm_struct structures (tsk->mm) */ | 138 | /* SLAB cache for mm_struct structures (tsk->mm) */ |
137 | static struct kmem_cache *mm_cachep; | 139 | static struct kmem_cache *mm_cachep; |
138 | 140 | ||
141 | static void account_kernel_stack(struct thread_info *ti, int account) | ||
142 | { | ||
143 | struct zone *zone = page_zone(virt_to_page(ti)); | ||
144 | |||
145 | mod_zone_page_state(zone, NR_KERNEL_STACK, account); | ||
146 | } | ||
147 | |||
139 | void free_task(struct task_struct *tsk) | 148 | void free_task(struct task_struct *tsk) |
140 | { | 149 | { |
141 | prop_local_destroy_single(&tsk->dirties); | 150 | prop_local_destroy_single(&tsk->dirties); |
151 | account_kernel_stack(tsk->stack, -1); | ||
142 | free_thread_info(tsk->stack); | 152 | free_thread_info(tsk->stack); |
143 | rt_mutex_debug_task_free(tsk); | 153 | rt_mutex_debug_task_free(tsk); |
144 | ftrace_graph_exit_task(tsk); | 154 | ftrace_graph_exit_task(tsk); |
@@ -253,6 +263,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
253 | tsk->btrace_seq = 0; | 263 | tsk->btrace_seq = 0; |
254 | #endif | 264 | #endif |
255 | tsk->splice_pipe = NULL; | 265 | tsk->splice_pipe = NULL; |
266 | |||
267 | account_kernel_stack(ti, 1); | ||
268 | |||
256 | return tsk; | 269 | return tsk; |
257 | 270 | ||
258 | out: | 271 | out: |
@@ -288,6 +301,9 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
288 | rb_link = &mm->mm_rb.rb_node; | 301 | rb_link = &mm->mm_rb.rb_node; |
289 | rb_parent = NULL; | 302 | rb_parent = NULL; |
290 | pprev = &mm->mmap; | 303 | pprev = &mm->mmap; |
304 | retval = ksm_fork(mm, oldmm); | ||
305 | if (retval) | ||
306 | goto out; | ||
291 | 307 | ||
292 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { | 308 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { |
293 | struct file *file; | 309 | struct file *file; |
@@ -424,7 +440,8 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | |||
424 | atomic_set(&mm->mm_count, 1); | 440 | atomic_set(&mm->mm_count, 1); |
425 | init_rwsem(&mm->mmap_sem); | 441 | init_rwsem(&mm->mmap_sem); |
426 | INIT_LIST_HEAD(&mm->mmlist); | 442 | INIT_LIST_HEAD(&mm->mmlist); |
427 | mm->flags = (current->mm) ? current->mm->flags : default_dump_filter; | 443 | mm->flags = (current->mm) ? |
444 | (current->mm->flags & MMF_INIT_MASK) : default_dump_filter; | ||
428 | mm->core_state = NULL; | 445 | mm->core_state = NULL; |
429 | mm->nr_ptes = 0; | 446 | mm->nr_ptes = 0; |
430 | set_mm_counter(mm, file_rss, 0); | 447 | set_mm_counter(mm, file_rss, 0); |
@@ -485,6 +502,7 @@ void mmput(struct mm_struct *mm) | |||
485 | 502 | ||
486 | if (atomic_dec_and_test(&mm->mm_users)) { | 503 | if (atomic_dec_and_test(&mm->mm_users)) { |
487 | exit_aio(mm); | 504 | exit_aio(mm); |
505 | ksm_exit(mm); | ||
488 | exit_mmap(mm); | 506 | exit_mmap(mm); |
489 | set_mm_exe_file(mm, NULL); | 507 | set_mm_exe_file(mm, NULL); |
490 | if (!list_empty(&mm->mmlist)) { | 508 | if (!list_empty(&mm->mmlist)) { |
@@ -788,10 +806,10 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig) | |||
788 | thread_group_cputime_init(sig); | 806 | thread_group_cputime_init(sig); |
789 | 807 | ||
790 | /* Expiration times and increments. */ | 808 | /* Expiration times and increments. */ |
791 | sig->it_virt_expires = cputime_zero; | 809 | sig->it[CPUCLOCK_PROF].expires = cputime_zero; |
792 | sig->it_virt_incr = cputime_zero; | 810 | sig->it[CPUCLOCK_PROF].incr = cputime_zero; |
793 | sig->it_prof_expires = cputime_zero; | 811 | sig->it[CPUCLOCK_VIRT].expires = cputime_zero; |
794 | sig->it_prof_incr = cputime_zero; | 812 | sig->it[CPUCLOCK_VIRT].incr = cputime_zero; |
795 | 813 | ||
796 | /* Cached expiration times. */ | 814 | /* Cached expiration times. */ |
797 | sig->cputime_expires.prof_exp = cputime_zero; | 815 | sig->cputime_expires.prof_exp = cputime_zero; |
@@ -849,6 +867,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
849 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; | 867 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; |
850 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; | 868 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; |
851 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; | 869 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; |
870 | sig->maxrss = sig->cmaxrss = 0; | ||
852 | task_io_accounting_init(&sig->ioac); | 871 | task_io_accounting_init(&sig->ioac); |
853 | sig->sum_sched_runtime = 0; | 872 | sig->sum_sched_runtime = 0; |
854 | taskstats_tgid_init(sig); | 873 | taskstats_tgid_init(sig); |
@@ -863,6 +882,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
863 | 882 | ||
864 | tty_audit_fork(sig); | 883 | tty_audit_fork(sig); |
865 | 884 | ||
885 | sig->oom_adj = current->signal->oom_adj; | ||
886 | |||
866 | return 0; | 887 | return 0; |
867 | } | 888 | } |
868 | 889 | ||
@@ -1075,6 +1096,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1075 | 1096 | ||
1076 | p->bts = NULL; | 1097 | p->bts = NULL; |
1077 | 1098 | ||
1099 | p->stack_start = stack_start; | ||
1100 | |||
1078 | /* Perform scheduler related setup. Assign this task to a CPU. */ | 1101 | /* Perform scheduler related setup. Assign this task to a CPU. */ |
1079 | sched_fork(p, clone_flags); | 1102 | sched_fork(p, clone_flags); |
1080 | 1103 | ||