aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-06-27 20:06:43 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2013-07-03 10:19:23 -0400
commit2473f3e7a97ce8bc0fe7596cdb361b21221418eb (patch)
tree8657b89498beb32d5b648b1db1a00dfd24a62d9a /kernel
parent1a7fa510b38e518d11365883934f1afa41625424 (diff)
posix_cpu_timers: consolidate expired timers check
Consolidate the common code amongst per thread and per process timers list on tick time. List traversal, expiry check and subsequent updates can be shared in a common helper. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Stanislaw Gruszka <sgruszka@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Ingo Molnar <mingo@elte.hu> Cc: Oleg Nesterov <oleg@redhat.com> Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com> Cc: Olivier Langlois <olivier@trillion01.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/posix-cpu-timers.c118
1 files changed, 33 insertions, 85 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index b1450cee6d6d..92a4fbf44f86 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -862,6 +862,28 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
862 } 862 }
863} 863}
864 864
865static unsigned long long
866check_timers_list(struct list_head *timers,
867 struct list_head *firing,
868 unsigned long long curr)
869{
870 int maxfire = 20;
871
872 while (!list_empty(timers)) {
873 struct cpu_timer_list *t;
874
875 t = list_first_entry(timers, struct cpu_timer_list, entry);
876
877 if (!--maxfire || curr < t->expires)
878 return t->expires;
879
880 t->firing = 1;
881 list_move_tail(&t->entry, firing);
882 }
883
884 return 0;
885}
886
865/* 887/*
866 * Check for any per-thread CPU timers that have fired and move them off 888 * Check for any per-thread CPU timers that have fired and move them off
867 * the tsk->cpu_timers[N] list onto the firing list. Here we update the 889 * the tsk->cpu_timers[N] list onto the firing list. Here we update the
@@ -870,54 +892,20 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
870static void check_thread_timers(struct task_struct *tsk, 892static void check_thread_timers(struct task_struct *tsk,
871 struct list_head *firing) 893 struct list_head *firing)
872{ 894{
873 int maxfire;
874 struct list_head *timers = tsk->cpu_timers; 895 struct list_head *timers = tsk->cpu_timers;
875 struct signal_struct *const sig = tsk->signal; 896 struct signal_struct *const sig = tsk->signal;
897 struct task_cputime *tsk_expires = &tsk->cputime_expires;
898 unsigned long long expires;
876 unsigned long soft; 899 unsigned long soft;
877 900
878 maxfire = 20; 901 expires = check_timers_list(timers, firing, prof_ticks(tsk));
879 tsk->cputime_expires.prof_exp = 0; 902 tsk_expires->prof_exp = expires_to_cputime(expires);
880 while (!list_empty(timers)) {
881 struct cpu_timer_list *t = list_first_entry(timers,
882 struct cpu_timer_list,
883 entry);
884 if (!--maxfire || prof_ticks(tsk) < t->expires) {
885 tsk->cputime_expires.prof_exp = expires_to_cputime(t->expires);
886 break;
887 }
888 t->firing = 1;
889 list_move_tail(&t->entry, firing);
890 }
891 903
892 ++timers; 904 expires = check_timers_list(++timers, firing, virt_ticks(tsk));
893 maxfire = 20; 905 tsk_expires->virt_exp = expires_to_cputime(expires);
894 tsk->cputime_expires.virt_exp = 0;
895 while (!list_empty(timers)) {
896 struct cpu_timer_list *t = list_first_entry(timers,
897 struct cpu_timer_list,
898 entry);
899 if (!--maxfire || virt_ticks(tsk) < t->expires) {
900 tsk->cputime_expires.virt_exp = expires_to_cputime(t->expires);
901 break;
902 }
903 t->firing = 1;
904 list_move_tail(&t->entry, firing);
905 }
906 906
907 ++timers; 907 tsk_expires->sched_exp = check_timers_list(++timers, firing,
908 maxfire = 20; 908 tsk->se.sum_exec_runtime);
909 tsk->cputime_expires.sched_exp = 0;
910 while (!list_empty(timers)) {
911 struct cpu_timer_list *t = list_first_entry(timers,
912 struct cpu_timer_list,
913 entry);
914 if (!--maxfire || tsk->se.sum_exec_runtime < t->expires) {
915 tsk->cputime_expires.sched_exp = t->expires;
916 break;
917 }
918 t->firing = 1;
919 list_move_tail(&t->entry, firing);
920 }
921 909
922 /* 910 /*
923 * Check for the special case thread timers. 911 * Check for the special case thread timers.
@@ -1002,7 +990,6 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
1002static void check_process_timers(struct task_struct *tsk, 990static void check_process_timers(struct task_struct *tsk,
1003 struct list_head *firing) 991 struct list_head *firing)
1004{ 992{
1005 int maxfire;
1006 struct signal_struct *const sig = tsk->signal; 993 struct signal_struct *const sig = tsk->signal;
1007 unsigned long long utime, ptime, virt_expires, prof_expires; 994 unsigned long long utime, ptime, virt_expires, prof_expires;
1008 unsigned long long sum_sched_runtime, sched_expires; 995 unsigned long long sum_sched_runtime, sched_expires;
@@ -1017,49 +1004,10 @@ static void check_process_timers(struct task_struct *tsk,
1017 utime = cputime_to_expires(cputime.utime); 1004 utime = cputime_to_expires(cputime.utime);
1018 ptime = utime + cputime_to_expires(cputime.stime); 1005 ptime = utime + cputime_to_expires(cputime.stime);
1019 sum_sched_runtime = cputime.sum_exec_runtime; 1006 sum_sched_runtime = cputime.sum_exec_runtime;
1020 maxfire = 20;
1021 prof_expires = 0;
1022 while (!list_empty(timers)) {
1023 struct cpu_timer_list *tl = list_first_entry(timers,
1024 struct cpu_timer_list,
1025 entry);
1026 if (!--maxfire || ptime < tl->expires) {
1027 prof_expires = tl->expires;
1028 break;
1029 }
1030 tl->firing = 1;
1031 list_move_tail(&tl->entry, firing);
1032 }
1033 1007
1034 ++timers; 1008 prof_expires = check_timers_list(timers, firing, ptime);
1035 maxfire = 20; 1009 virt_expires = check_timers_list(++timers, firing, utime);
1036 virt_expires = 0; 1010 sched_expires = check_timers_list(++timers, firing, sum_sched_runtime);
1037 while (!list_empty(timers)) {
1038 struct cpu_timer_list *tl = list_first_entry(timers,
1039 struct cpu_timer_list,
1040 entry);
1041 if (!--maxfire || utime < tl->expires) {
1042 virt_expires = tl->expires;
1043 break;
1044 }
1045 tl->firing = 1;
1046 list_move_tail(&tl->entry, firing);
1047 }
1048
1049 ++timers;
1050 maxfire = 20;
1051 sched_expires = 0;
1052 while (!list_empty(timers)) {
1053 struct cpu_timer_list *tl = list_first_entry(timers,
1054 struct cpu_timer_list,
1055 entry);
1056 if (!--maxfire || sum_sched_runtime < tl->expires) {
1057 sched_expires = tl->expires;
1058 break;
1059 }
1060 tl->firing = 1;
1061 list_move_tail(&tl->entry, firing);
1062 }
1063 1011
1064 /* 1012 /*
1065 * Check for the special case process timers. 1013 * Check for the special case process timers.