aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-10-23 13:02:50 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-23 13:02:50 -0400
commite80eda94d3eaf1d12cfc97878eff77cd679dabc9 (patch)
tree38ab17e7b9839297708a6982d661c3725d181c3a
parentd475f3f47a0427dfee483cecf9a7e9109e991423 (diff)
Posix timers: limit number of timers firing at once
Bursty timers aren't good for anybody, very much including latency for other programs when we trigger lots of timers in interrupt context. So set a random limit, after which we'll handle the rest on the next timer tick. Noted by Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--kernel/posix-cpu-timers.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 7a51a5597c33..d30b304a3384 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -961,14 +961,16 @@ void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
961static void check_thread_timers(struct task_struct *tsk, 961static void check_thread_timers(struct task_struct *tsk,
962 struct list_head *firing) 962 struct list_head *firing)
963{ 963{
964 int maxfire;
964 struct list_head *timers = tsk->cpu_timers; 965 struct list_head *timers = tsk->cpu_timers;
965 966
967 maxfire = 20;
966 tsk->it_prof_expires = cputime_zero; 968 tsk->it_prof_expires = cputime_zero;
967 while (!list_empty(timers)) { 969 while (!list_empty(timers)) {
968 struct cpu_timer_list *t = list_entry(timers->next, 970 struct cpu_timer_list *t = list_entry(timers->next,
969 struct cpu_timer_list, 971 struct cpu_timer_list,
970 entry); 972 entry);
971 if (cputime_lt(prof_ticks(tsk), t->expires.cpu)) { 973 if (!--maxfire || cputime_lt(prof_ticks(tsk), t->expires.cpu)) {
972 tsk->it_prof_expires = t->expires.cpu; 974 tsk->it_prof_expires = t->expires.cpu;
973 break; 975 break;
974 } 976 }
@@ -977,12 +979,13 @@ static void check_thread_timers(struct task_struct *tsk,
977 } 979 }
978 980
979 ++timers; 981 ++timers;
982 maxfire = 20;
980 tsk->it_virt_expires = cputime_zero; 983 tsk->it_virt_expires = cputime_zero;
981 while (!list_empty(timers)) { 984 while (!list_empty(timers)) {
982 struct cpu_timer_list *t = list_entry(timers->next, 985 struct cpu_timer_list *t = list_entry(timers->next,
983 struct cpu_timer_list, 986 struct cpu_timer_list,
984 entry); 987 entry);
985 if (cputime_lt(virt_ticks(tsk), t->expires.cpu)) { 988 if (!--maxfire || cputime_lt(virt_ticks(tsk), t->expires.cpu)) {
986 tsk->it_virt_expires = t->expires.cpu; 989 tsk->it_virt_expires = t->expires.cpu;
987 break; 990 break;
988 } 991 }
@@ -991,12 +994,13 @@ static void check_thread_timers(struct task_struct *tsk,
991 } 994 }
992 995
993 ++timers; 996 ++timers;
997 maxfire = 20;
994 tsk->it_sched_expires = 0; 998 tsk->it_sched_expires = 0;
995 while (!list_empty(timers)) { 999 while (!list_empty(timers)) {
996 struct cpu_timer_list *t = list_entry(timers->next, 1000 struct cpu_timer_list *t = list_entry(timers->next,
997 struct cpu_timer_list, 1001 struct cpu_timer_list,
998 entry); 1002 entry);
999 if (tsk->sched_time < t->expires.sched) { 1003 if (!--maxfire || tsk->sched_time < t->expires.sched) {
1000 tsk->it_sched_expires = t->expires.sched; 1004 tsk->it_sched_expires = t->expires.sched;
1001 break; 1005 break;
1002 } 1006 }
@@ -1013,6 +1017,7 @@ static void check_thread_timers(struct task_struct *tsk,
1013static void check_process_timers(struct task_struct *tsk, 1017static void check_process_timers(struct task_struct *tsk,
1014 struct list_head *firing) 1018 struct list_head *firing)
1015{ 1019{
1020 int maxfire;
1016 struct signal_struct *const sig = tsk->signal; 1021 struct signal_struct *const sig = tsk->signal;
1017 cputime_t utime, stime, ptime, virt_expires, prof_expires; 1022 cputime_t utime, stime, ptime, virt_expires, prof_expires;
1018 unsigned long long sched_time, sched_expires; 1023 unsigned long long sched_time, sched_expires;
@@ -1045,12 +1050,13 @@ static void check_process_timers(struct task_struct *tsk,
1045 } while (t != tsk); 1050 } while (t != tsk);
1046 ptime = cputime_add(utime, stime); 1051 ptime = cputime_add(utime, stime);
1047 1052
1053 maxfire = 20;
1048 prof_expires = cputime_zero; 1054 prof_expires = cputime_zero;
1049 while (!list_empty(timers)) { 1055 while (!list_empty(timers)) {
1050 struct cpu_timer_list *t = list_entry(timers->next, 1056 struct cpu_timer_list *t = list_entry(timers->next,
1051 struct cpu_timer_list, 1057 struct cpu_timer_list,
1052 entry); 1058 entry);
1053 if (cputime_lt(ptime, t->expires.cpu)) { 1059 if (!--maxfire || cputime_lt(ptime, t->expires.cpu)) {
1054 prof_expires = t->expires.cpu; 1060 prof_expires = t->expires.cpu;
1055 break; 1061 break;
1056 } 1062 }
@@ -1059,12 +1065,13 @@ static void check_process_timers(struct task_struct *tsk,
1059 } 1065 }
1060 1066
1061 ++timers; 1067 ++timers;
1068 maxfire = 20;
1062 virt_expires = cputime_zero; 1069 virt_expires = cputime_zero;
1063 while (!list_empty(timers)) { 1070 while (!list_empty(timers)) {
1064 struct cpu_timer_list *t = list_entry(timers->next, 1071 struct cpu_timer_list *t = list_entry(timers->next,
1065 struct cpu_timer_list, 1072 struct cpu_timer_list,
1066 entry); 1073 entry);
1067 if (cputime_lt(utime, t->expires.cpu)) { 1074 if (!--maxfire || cputime_lt(utime, t->expires.cpu)) {
1068 virt_expires = t->expires.cpu; 1075 virt_expires = t->expires.cpu;
1069 break; 1076 break;
1070 } 1077 }
@@ -1073,12 +1080,13 @@ static void check_process_timers(struct task_struct *tsk,
1073 } 1080 }
1074 1081
1075 ++timers; 1082 ++timers;
1083 maxfire = 20;
1076 sched_expires = 0; 1084 sched_expires = 0;
1077 while (!list_empty(timers)) { 1085 while (!list_empty(timers)) {
1078 struct cpu_timer_list *t = list_entry(timers->next, 1086 struct cpu_timer_list *t = list_entry(timers->next,
1079 struct cpu_timer_list, 1087 struct cpu_timer_list,
1080 entry); 1088 entry);
1081 if (sched_time < t->expires.sched) { 1089 if (!--maxfire || sched_time < t->expires.sched) {
1082 sched_expires = t->expires.sched; 1090 sched_expires = t->expires.sched;
1083 break; 1091 break;
1084 } 1092 }