diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 113 |
1 files changed, 70 insertions, 43 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 7ce2ebe8479..2a372a0e206 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 | */ | ||
| 778 | static 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 | |||
| 762 | static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | 800 | static 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(¤t->signal->count); | 806 | ret = thread_group_cputime_clone_thread(current); |
| 769 | atomic_inc(¤t->signal->live); | 807 | if (likely(!ret)) { |
| 770 | return 0; | 808 | atomic_inc(¤t->signal->count); |
| 809 | atomic_inc(¤t->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 | ||
| 838 | void __cleanup_signal(struct signal_struct *sig) | 865 | void __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 | */ | ||
| 920 | static 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(¤t->signal->cpu_timers[0]) || | ||
| 1211 | !list_empty(¤t->signal->cpu_timers[1]) || | ||
| 1212 | !list_empty(¤t->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) |
