aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c33
1 files changed, 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) */
137static struct kmem_cache *mm_cachep; 139static struct kmem_cache *mm_cachep;
138 140
141static 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
139void free_task(struct task_struct *tsk) 148void 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
258out: 271out:
@@ -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