aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2019-08-21 15:09:20 -0400
committerThomas Gleixner <tglx@linutronix.de>2019-08-28 05:50:41 -0400
commit1cd07c0b94f2c320270d76edb7dd49bceb09c1df (patch)
tree82bd5d32e3dc433968c1b12114755069a36cefba
parent2bbdbdae05167c688b6d3499a7dab74208b80a22 (diff)
posix-cpu-timers: Consolidate timer expiry further
With the array based samples and expiry cache, the expiry function can use a loop to collect timers from the clock specific lists. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Frederic Weisbecker <frederic@kernel.org> Link: https://lkml.kernel.org/r/20190821192922.365469982@linutronix.de
-rw-r--r--kernel/time/posix-cpu-timers.c63
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
755static 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
755static inline void check_dl_overrun(struct task_struct *tsk) 767static 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)
768static void check_thread_timers(struct task_struct *tsk, 780static 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;