aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c92
1 files changed, 50 insertions, 42 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 30de644a40c4..44e64d7ba29b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -759,15 +759,44 @@ void __cleanup_sighand(struct sighand_struct *sighand)
759 kmem_cache_free(sighand_cachep, sighand); 759 kmem_cache_free(sighand_cachep, sighand);
760} 760}
761 761
762
763/*
764 * Initialize POSIX timer handling for a thread group.
765 */
766static void posix_cpu_timers_init_group(struct signal_struct *sig)
767{
768 /* Thread group counters. */
769 thread_group_cputime_init(sig);
770
771 /* Expiration times and increments. */
772 sig->it_virt_expires = cputime_zero;
773 sig->it_virt_incr = cputime_zero;
774 sig->it_prof_expires = cputime_zero;
775 sig->it_prof_incr = cputime_zero;
776
777 /* Cached expiration times. */
778 sig->cputime_expires.prof_exp = cputime_zero;
779 sig->cputime_expires.virt_exp = cputime_zero;
780 sig->cputime_expires.sched_exp = 0;
781
782 /* The timer lists. */
783 INIT_LIST_HEAD(&sig->cpu_timers[0]);
784 INIT_LIST_HEAD(&sig->cpu_timers[1]);
785 INIT_LIST_HEAD(&sig->cpu_timers[2]);
786}
787
762static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) 788static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
763{ 789{
764 struct signal_struct *sig; 790 struct signal_struct *sig;
765 int ret; 791 int ret;
766 792
767 if (clone_flags & CLONE_THREAD) { 793 if (clone_flags & CLONE_THREAD) {
768 atomic_inc(&current->signal->count); 794 ret = thread_group_cputime_clone_thread(current);
769 atomic_inc(&current->signal->live); 795 if (likely(!ret)) {
770 return 0; 796 atomic_inc(&current->signal->count);
797 atomic_inc(&current->signal->live);
798 }
799 return ret;
771 } 800 }
772 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); 801 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
773 tsk->signal = sig; 802 tsk->signal = sig;
@@ -795,40 +824,25 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
795 sig->it_real_incr.tv64 = 0; 824 sig->it_real_incr.tv64 = 0;
796 sig->real_timer.function = it_real_fn; 825 sig->real_timer.function = it_real_fn;
797 826
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 */ 827 sig->leader = 0; /* session leadership doesn't inherit */
804 sig->tty_old_pgrp = NULL; 828 sig->tty_old_pgrp = NULL;
805 sig->tty = NULL; 829 sig->tty = NULL;
806 830
807 sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; 831 sig->cutime = sig->cstime = cputime_zero;
808 sig->gtime = cputime_zero; 832 sig->gtime = cputime_zero;
809 sig->cgtime = cputime_zero; 833 sig->cgtime = cputime_zero;
810 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; 834 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
811 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; 835 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
812 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; 836 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
813 task_io_accounting_init(&sig->ioac); 837 task_io_accounting_init(&sig->ioac);
814 sig->sum_sched_runtime = 0;
815 INIT_LIST_HEAD(&sig->cpu_timers[0]);
816 INIT_LIST_HEAD(&sig->cpu_timers[1]);
817 INIT_LIST_HEAD(&sig->cpu_timers[2]);
818 taskstats_tgid_init(sig); 838 taskstats_tgid_init(sig);
819 839
820 task_lock(current->group_leader); 840 task_lock(current->group_leader);
821 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); 841 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
822 task_unlock(current->group_leader); 842 task_unlock(current->group_leader);
823 843
824 if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { 844 posix_cpu_timers_init_group(sig);
825 /* 845
826 * New sole thread in the process gets an expiry time
827 * of the whole CPU time limit.
828 */
829 tsk->it_prof_expires =
830 secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
831 }
832 acct_init_pacct(&sig->pacct); 846 acct_init_pacct(&sig->pacct);
833 847
834 tty_audit_fork(sig); 848 tty_audit_fork(sig);
@@ -838,6 +852,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
838 852
839void __cleanup_signal(struct signal_struct *sig) 853void __cleanup_signal(struct signal_struct *sig)
840{ 854{
855 thread_group_cputime_free(sig);
841 exit_thread_group_keys(sig); 856 exit_thread_group_keys(sig);
842 tty_kref_put(sig->tty); 857 tty_kref_put(sig->tty);
843 kmem_cache_free(signal_cachep, sig); 858 kmem_cache_free(signal_cachep, sig);
@@ -888,6 +903,19 @@ void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
888#endif /* CONFIG_MM_OWNER */ 903#endif /* CONFIG_MM_OWNER */
889 904
890/* 905/*
906 * Initialize POSIX timer handling for a single task.
907 */
908static void posix_cpu_timers_init(struct task_struct *tsk)
909{
910 tsk->cputime_expires.prof_exp = cputime_zero;
911 tsk->cputime_expires.virt_exp = cputime_zero;
912 tsk->cputime_expires.sched_exp = 0;
913 INIT_LIST_HEAD(&tsk->cpu_timers[0]);
914 INIT_LIST_HEAD(&tsk->cpu_timers[1]);
915 INIT_LIST_HEAD(&tsk->cpu_timers[2]);
916}
917
918/*
891 * This creates a new process as a copy of the old one, 919 * This creates a new process as a copy of the old one,
892 * but does not actually start it yet. 920 * but does not actually start it yet.
893 * 921 *
@@ -997,12 +1025,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
997 task_io_accounting_init(&p->ioac); 1025 task_io_accounting_init(&p->ioac);
998 acct_clear_integrals(p); 1026 acct_clear_integrals(p);
999 1027
1000 p->it_virt_expires = cputime_zero; 1028 posix_cpu_timers_init(p);
1001 p->it_prof_expires = cputime_zero;
1002 p->it_sched_expires = 0;
1003 INIT_LIST_HEAD(&p->cpu_timers[0]);
1004 INIT_LIST_HEAD(&p->cpu_timers[1]);
1005 INIT_LIST_HEAD(&p->cpu_timers[2]);
1006 1029
1007 p->lock_depth = -1; /* -1 = no lock */ 1030 p->lock_depth = -1; /* -1 = no lock */
1008 do_posix_clock_monotonic_gettime(&p->start_time); 1031 do_posix_clock_monotonic_gettime(&p->start_time);
@@ -1203,21 +1226,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1203 if (clone_flags & CLONE_THREAD) { 1226 if (clone_flags & CLONE_THREAD) {
1204 p->group_leader = current->group_leader; 1227 p->group_leader = current->group_leader;
1205 list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); 1228 list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
1206
1207 if (!cputime_eq(current->signal->it_virt_expires,
1208 cputime_zero) ||
1209 !cputime_eq(current->signal->it_prof_expires,
1210 cputime_zero) ||
1211 current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY ||
1212 !list_empty(&current->signal->cpu_timers[0]) ||
1213 !list_empty(&current->signal->cpu_timers[1]) ||
1214 !list_empty(&current->signal->cpu_timers[2])) {
1215 /*
1216 * Have child wake up on its first tick to check
1217 * for process CPU timers.
1218 */
1219 p->it_prof_expires = jiffies_to_cputime(1);
1220 }
1221 } 1229 }
1222 1230
1223 if (likely(p->pid)) { 1231 if (likely(p->pid)) {