diff options
Diffstat (limited to 'kernel/time/posix-cpu-timers.c')
-rw-r--r-- | kernel/time/posix-cpu-timers.c | 63 |
1 files changed, 30 insertions, 33 deletions
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index cf85292575c5..caafdfdd6f0f 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c | |||
@@ -752,6 +752,18 @@ check_timers_list(struct list_head *timers, | |||
752 | return U64_MAX; | 752 | return U64_MAX; |
753 | } | 753 | } |
754 | 754 | ||
755 | static void collect_posix_cputimers(struct posix_cputimers *pct, | ||
756 | u64 *samples, struct list_head *firing) | ||
757 | { | ||
758 | struct posix_cputimer_base *base = pct->bases; | ||
759 | int i; | ||
760 | |||
761 | for (i = 0; i < CPUCLOCK_MAX; i++, base++) { | ||
762 | base->nextevt = check_timers_list(&base->cpu_timers, firing, | ||
763 | samples[i]); | ||
764 | } | ||
765 | } | ||
766 | |||
755 | static inline void check_dl_overrun(struct task_struct *tsk) | 767 | static inline void check_dl_overrun(struct task_struct *tsk) |
756 | { | 768 | { |
757 | if (tsk->dl.dl_overrun) { | 769 | if (tsk->dl.dl_overrun) { |
@@ -768,25 +780,18 @@ static inline void check_dl_overrun(struct task_struct *tsk) | |||
768 | static void check_thread_timers(struct task_struct *tsk, | 780 | static void check_thread_timers(struct task_struct *tsk, |
769 | struct list_head *firing) | 781 | struct list_head *firing) |
770 | { | 782 | { |
771 | struct posix_cputimer_base *base = tsk->posix_cputimers.bases; | 783 | struct posix_cputimers *pct = &tsk->posix_cputimers; |
784 | u64 samples[CPUCLOCK_MAX]; | ||
772 | unsigned long soft; | 785 | unsigned long soft; |
773 | u64 stime, utime; | ||
774 | 786 | ||
775 | if (dl_task(tsk)) | 787 | if (dl_task(tsk)) |
776 | check_dl_overrun(tsk); | 788 | check_dl_overrun(tsk); |
777 | 789 | ||
778 | if (expiry_cache_is_inactive(&tsk->posix_cputimers)) | 790 | if (expiry_cache_is_inactive(pct)) |
779 | return; | 791 | return; |
780 | 792 | ||
781 | task_cputime(tsk, &utime, &stime); | 793 | task_sample_cputime(tsk, samples); |
782 | 794 | collect_posix_cputimers(pct, samples, firing); | |
783 | base->nextevt = check_timers_list(&base->cpu_timers, firing, | ||
784 | utime + stime); | ||
785 | base++; | ||
786 | base->nextevt = check_timers_list(&base->cpu_timers, firing, utime); | ||
787 | base++; | ||
788 | base->nextevt = check_timers_list(&base->cpu_timers, firing, | ||
789 | tsk->se.sum_exec_runtime); | ||
790 | 795 | ||
791 | /* | 796 | /* |
792 | * Check for the special case thread timers. | 797 | * Check for the special case thread timers. |
@@ -825,7 +830,7 @@ static void check_thread_timers(struct task_struct *tsk, | |||
825 | } | 830 | } |
826 | } | 831 | } |
827 | 832 | ||
828 | if (expiry_cache_is_inactive(&tsk->posix_cputimers)) | 833 | if (expiry_cache_is_inactive(pct)) |
829 | tick_dep_clear_task(tsk, TICK_DEP_BIT_POSIX_TIMER); | 834 | tick_dep_clear_task(tsk, TICK_DEP_BIT_POSIX_TIMER); |
830 | } | 835 | } |
831 | 836 | ||
@@ -869,15 +874,15 @@ static void check_process_timers(struct task_struct *tsk, | |||
869 | struct list_head *firing) | 874 | struct list_head *firing) |
870 | { | 875 | { |
871 | struct signal_struct *const sig = tsk->signal; | 876 | struct signal_struct *const sig = tsk->signal; |
872 | struct posix_cputimer_base *base = sig->posix_cputimers.bases; | 877 | struct posix_cputimers *pct = &sig->posix_cputimers; |
873 | u64 virt_exp, prof_exp, sched_exp, samples[CPUCLOCK_MAX]; | 878 | u64 samples[CPUCLOCK_MAX]; |
874 | unsigned long soft; | 879 | unsigned long soft; |
875 | 880 | ||
876 | /* | 881 | /* |
877 | * If cputimer is not running, then there are no active | 882 | * If cputimer is not running, then there are no active |
878 | * process wide timers (POSIX 1.b, itimers, RLIMIT_CPU). | 883 | * process wide timers (POSIX 1.b, itimers, RLIMIT_CPU). |
879 | */ | 884 | */ |
880 | if (!READ_ONCE(tsk->signal->cputimer.running)) | 885 | if (!READ_ONCE(sig->cputimer.running)) |
881 | return; | 886 | return; |
882 | 887 | ||
883 | /* | 888 | /* |
@@ -891,21 +896,17 @@ static void check_process_timers(struct task_struct *tsk, | |||
891 | * so the sample can be taken directly. | 896 | * so the sample can be taken directly. |
892 | */ | 897 | */ |
893 | proc_sample_cputime_atomic(&sig->cputimer.cputime_atomic, samples); | 898 | proc_sample_cputime_atomic(&sig->cputimer.cputime_atomic, samples); |
894 | 899 | collect_posix_cputimers(pct, samples, firing); | |
895 | prof_exp = check_timers_list(&base[CPUCLOCK_PROF].cpu_timers, | ||
896 | firing, samples[CPUCLOCK_PROF]); | ||
897 | virt_exp = check_timers_list(&base[CPUCLOCK_VIRT].cpu_timers, | ||
898 | firing, samples[CPUCLOCK_VIRT]); | ||
899 | sched_exp = check_timers_list(&base[CPUCLOCK_SCHED].cpu_timers, | ||
900 | firing, samples[CPUCLOCK_SCHED]); | ||
901 | 900 | ||
902 | /* | 901 | /* |
903 | * Check for the special case process timers. | 902 | * Check for the special case process timers. |
904 | */ | 903 | */ |
905 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_PROF], &prof_exp, | 904 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_PROF], |
905 | &pct->bases[CPUCLOCK_PROF].nextevt, | ||
906 | samples[CPUCLOCK_PROF], SIGPROF); | 906 | samples[CPUCLOCK_PROF], SIGPROF); |
907 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_exp, | 907 | check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], |
908 | samples[CPUCLOCK_PROF], SIGVTALRM); | 908 | &pct->bases[CPUCLOCK_VIRT].nextevt, |
909 | samples[CPUCLOCK_VIRT], SIGVTALRM); | ||
909 | 910 | ||
910 | soft = task_rlimit(tsk, RLIMIT_CPU); | 911 | soft = task_rlimit(tsk, RLIMIT_CPU); |
911 | if (soft != RLIM_INFINITY) { | 912 | if (soft != RLIM_INFINITY) { |
@@ -940,15 +941,11 @@ static void check_process_timers(struct task_struct *tsk, | |||
940 | } | 941 | } |
941 | } | 942 | } |
942 | softns = soft * NSEC_PER_SEC; | 943 | softns = soft * NSEC_PER_SEC; |
943 | if (softns < prof_exp) | 944 | if (softns < pct->bases[CPUCLOCK_PROF].nextevt) |
944 | prof_exp = softns; | 945 | pct->bases[CPUCLOCK_PROF].nextevt = softns; |
945 | } | 946 | } |
946 | 947 | ||
947 | base[CPUCLOCK_PROF].nextevt = prof_exp; | 948 | if (expiry_cache_is_inactive(pct)) |
948 | base[CPUCLOCK_VIRT].nextevt = virt_exp; | ||
949 | base[CPUCLOCK_SCHED].nextevt = sched_exp; | ||
950 | |||
951 | if (expiry_cache_is_inactive(&sig->posix_cputimers)) | ||
952 | stop_process_timers(sig); | 949 | stop_process_timers(sig); |
953 | 950 | ||
954 | sig->cputimer.checking_timer = false; | 951 | sig->cputimer.checking_timer = false; |