aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c113
1 files changed, 70 insertions, 43 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 7ce2ebe84796..2a372a0e206f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -40,6 +40,7 @@
40#include <linux/jiffies.h> 40#include <linux/jiffies.h>
41#include <linux/tracehook.h> 41#include <linux/tracehook.h>
42#include <linux/futex.h> 42#include <linux/futex.h>
43#include <linux/compat.h>
43#include <linux/task_io_accounting_ops.h> 44#include <linux/task_io_accounting_ops.h>
44#include <linux/rcupdate.h> 45#include <linux/rcupdate.h>
45#include <linux/ptrace.h> 46#include <linux/ptrace.h>
@@ -58,6 +59,7 @@
58#include <linux/tty.h> 59#include <linux/tty.h>
59#include <linux/proc_fs.h> 60#include <linux/proc_fs.h>
60#include <linux/blkdev.h> 61#include <linux/blkdev.h>
62#include <trace/sched.h>
61 63
62#include <asm/pgtable.h> 64#include <asm/pgtable.h>
63#include <asm/pgalloc.h> 65#include <asm/pgalloc.h>
@@ -518,6 +520,16 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
518{ 520{
519 struct completion *vfork_done = tsk->vfork_done; 521 struct completion *vfork_done = tsk->vfork_done;
520 522
523 /* Get rid of any futexes when releasing the mm */
524#ifdef CONFIG_FUTEX
525 if (unlikely(tsk->robust_list))
526 exit_robust_list(tsk);
527#ifdef CONFIG_COMPAT
528 if (unlikely(tsk->compat_robust_list))
529 compat_exit_robust_list(tsk);
530#endif
531#endif
532
521 /* Get rid of any cached register state */ 533 /* Get rid of any cached register state */
522 deactivate_mm(tsk, mm); 534 deactivate_mm(tsk, mm);
523 535
@@ -759,15 +771,44 @@ void __cleanup_sighand(struct sighand_struct *sighand)
759 kmem_cache_free(sighand_cachep, sighand); 771 kmem_cache_free(sighand_cachep, sighand);
760} 772}
761 773
774
775/*
776 * Initialize POSIX timer handling for a thread group.
777 */
778static void posix_cpu_timers_init_group(struct signal_struct *sig)
779{
780 /* Thread group counters. */
781 thread_group_cputime_init(sig);
782
783 /* Expiration times and increments. */
784 sig->it_virt_expires = cputime_zero;
785 sig->it_virt_incr = cputime_zero;
786 sig->it_prof_expires = cputime_zero;
787 sig->it_prof_incr = cputime_zero;
788
789 /* Cached expiration times. */
790 sig->cputime_expires.prof_exp = cputime_zero;
791 sig->cputime_expires.virt_exp = cputime_zero;
792 sig->cputime_expires.sched_exp = 0;
793
794 /* The timer lists. */
795 INIT_LIST_HEAD(&sig->cpu_timers[0]);
796 INIT_LIST_HEAD(&sig->cpu_timers[1]);
797 INIT_LIST_HEAD(&sig->cpu_timers[2]);
798}
799
762static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) 800static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
763{ 801{
764 struct signal_struct *sig; 802 struct signal_struct *sig;
765 int ret; 803 int ret;
766 804
767 if (clone_flags & CLONE_THREAD) { 805 if (clone_flags & CLONE_THREAD) {
768 atomic_inc(&current->signal->count); 806 ret = thread_group_cputime_clone_thread(current);
769 atomic_inc(&current->signal->live); 807 if (likely(!ret)) {
770 return 0; 808 atomic_inc(&current->signal->count);
809 atomic_inc(&current->signal->live);
810 }
811 return ret;
771 } 812 }
772 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); 813 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
773 tsk->signal = sig; 814 tsk->signal = sig;
@@ -795,39 +836,25 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
795 sig->it_real_incr.tv64 = 0; 836 sig->it_real_incr.tv64 = 0;
796 sig->real_timer.function = it_real_fn; 837 sig->real_timer.function = it_real_fn;
797 838
798 sig->it_virt_expires = cputime_zero;
799 sig->it_virt_incr = cputime_zero;
800 sig->it_prof_expires = cputime_zero;
801 sig->it_prof_incr = cputime_zero;
802
803 sig->leader = 0; /* session leadership doesn't inherit */ 839 sig->leader = 0; /* session leadership doesn't inherit */
804 sig->tty_old_pgrp = NULL; 840 sig->tty_old_pgrp = NULL;
841 sig->tty = NULL;
805 842
806 sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; 843 sig->cutime = sig->cstime = cputime_zero;
807 sig->gtime = cputime_zero; 844 sig->gtime = cputime_zero;
808 sig->cgtime = cputime_zero; 845 sig->cgtime = cputime_zero;
809 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; 846 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
810 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; 847 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
811 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; 848 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
812 task_io_accounting_init(&sig->ioac); 849 task_io_accounting_init(&sig->ioac);
813 sig->sum_sched_runtime = 0;
814 INIT_LIST_HEAD(&sig->cpu_timers[0]);
815 INIT_LIST_HEAD(&sig->cpu_timers[1]);
816 INIT_LIST_HEAD(&sig->cpu_timers[2]);
817 taskstats_tgid_init(sig); 850 taskstats_tgid_init(sig);
818 851
819 task_lock(current->group_leader); 852 task_lock(current->group_leader);
820 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); 853 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
821 task_unlock(current->group_leader); 854 task_unlock(current->group_leader);
822 855
823 if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { 856 posix_cpu_timers_init_group(sig);
824 /* 857
825 * New sole thread in the process gets an expiry time
826 * of the whole CPU time limit.
827 */
828 tsk->it_prof_expires =
829 secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
830 }
831 acct_init_pacct(&sig->pacct); 858 acct_init_pacct(&sig->pacct);
832 859
833 tty_audit_fork(sig); 860 tty_audit_fork(sig);
@@ -837,7 +864,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
837 864
838void __cleanup_signal(struct signal_struct *sig) 865void __cleanup_signal(struct signal_struct *sig)
839{ 866{
867 thread_group_cputime_free(sig);
840 exit_thread_group_keys(sig); 868 exit_thread_group_keys(sig);
869 tty_kref_put(sig->tty);
841 kmem_cache_free(signal_cachep, sig); 870 kmem_cache_free(signal_cachep, sig);
842} 871}
843 872
@@ -886,6 +915,19 @@ void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
886#endif /* CONFIG_MM_OWNER */ 915#endif /* CONFIG_MM_OWNER */
887 916
888/* 917/*
918 * Initialize POSIX timer handling for a single task.
919 */
920static void posix_cpu_timers_init(struct task_struct *tsk)
921{
922 tsk->cputime_expires.prof_exp = cputime_zero;
923 tsk->cputime_expires.virt_exp = cputime_zero;
924 tsk->cputime_expires.sched_exp = 0;
925 INIT_LIST_HEAD(&tsk->cpu_timers[0]);
926 INIT_LIST_HEAD(&tsk->cpu_timers[1]);
927 INIT_LIST_HEAD(&tsk->cpu_timers[2]);
928}
929
930/*
889 * This creates a new process as a copy of the old one, 931 * This creates a new process as a copy of the old one,
890 * but does not actually start it yet. 932 * but does not actually start it yet.
891 * 933 *
@@ -987,6 +1029,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
987 p->prev_utime = cputime_zero; 1029 p->prev_utime = cputime_zero;
988 p->prev_stime = cputime_zero; 1030 p->prev_stime = cputime_zero;
989 1031
1032 p->default_timer_slack_ns = current->timer_slack_ns;
1033
990#ifdef CONFIG_DETECT_SOFTLOCKUP 1034#ifdef CONFIG_DETECT_SOFTLOCKUP
991 p->last_switch_count = 0; 1035 p->last_switch_count = 0;
992 p->last_switch_timestamp = 0; 1036 p->last_switch_timestamp = 0;
@@ -995,12 +1039,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
995 task_io_accounting_init(&p->ioac); 1039 task_io_accounting_init(&p->ioac);
996 acct_clear_integrals(p); 1040 acct_clear_integrals(p);
997 1041
998 p->it_virt_expires = cputime_zero; 1042 posix_cpu_timers_init(p);
999 p->it_prof_expires = cputime_zero;
1000 p->it_sched_expires = 0;
1001 INIT_LIST_HEAD(&p->cpu_timers[0]);
1002 INIT_LIST_HEAD(&p->cpu_timers[1]);
1003 INIT_LIST_HEAD(&p->cpu_timers[2]);
1004 1043
1005 p->lock_depth = -1; /* -1 = no lock */ 1044 p->lock_depth = -1; /* -1 = no lock */
1006 do_posix_clock_monotonic_gettime(&p->start_time); 1045 do_posix_clock_monotonic_gettime(&p->start_time);
@@ -1201,21 +1240,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1201 if (clone_flags & CLONE_THREAD) { 1240 if (clone_flags & CLONE_THREAD) {
1202 p->group_leader = current->group_leader; 1241 p->group_leader = current->group_leader;
1203 list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); 1242 list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
1204
1205 if (!cputime_eq(current->signal->it_virt_expires,
1206 cputime_zero) ||
1207 !cputime_eq(current->signal->it_prof_expires,
1208 cputime_zero) ||
1209 current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY ||
1210 !list_empty(&current->signal->cpu_timers[0]) ||
1211 !list_empty(&current->signal->cpu_timers[1]) ||
1212 !list_empty(&current->signal->cpu_timers[2])) {
1213 /*
1214 * Have child wake up on its first tick to check
1215 * for process CPU timers.
1216 */
1217 p->it_prof_expires = jiffies_to_cputime(1);
1218 }
1219 } 1243 }
1220 1244
1221 if (likely(p->pid)) { 1245 if (likely(p->pid)) {
@@ -1227,7 +1251,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1227 p->nsproxy->pid_ns->child_reaper = p; 1251 p->nsproxy->pid_ns->child_reaper = p;
1228 1252
1229 p->signal->leader_pid = pid; 1253 p->signal->leader_pid = pid;
1230 p->signal->tty = current->signal->tty; 1254 tty_kref_put(p->signal->tty);
1255 p->signal->tty = tty_kref_get(current->signal->tty);
1231 set_task_pgrp(p, task_pgrp_nr(current)); 1256 set_task_pgrp(p, task_pgrp_nr(current));
1232 set_task_session(p, task_session_nr(current)); 1257 set_task_session(p, task_session_nr(current));
1233 attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); 1258 attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
@@ -1361,6 +1386,8 @@ long do_fork(unsigned long clone_flags,
1361 if (!IS_ERR(p)) { 1386 if (!IS_ERR(p)) {
1362 struct completion vfork; 1387 struct completion vfork;
1363 1388
1389 trace_sched_process_fork(current, p);
1390
1364 nr = task_pid_vnr(p); 1391 nr = task_pid_vnr(p);
1365 1392
1366 if (clone_flags & CLONE_PARENT_SETTID) 1393 if (clone_flags & CLONE_PARENT_SETTID)