diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2010-03-11 17:04:31 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-03-12 13:12:18 -0500 |
commit | 15365c108ea27598e265f8c13e7051d99ca5b0b9 (patch) | |
tree | 487cc70e96a3d6696f8f62fb7b6dbaacbc84ace5 | |
parent | 829b6c1ef488856c6a46a2f705f5068062d5f34c (diff) |
posix-cpu-timers: Reset expire cache when no timer is running
When a process deletes cpu timer or a timer expires we do not clear
the expiration cache sig->cputimer_expires.
As a result the fastpath_timer_check() which prevents us to loop over
all threads in case no timer is active is not working and we run the
slow path needlessly on every tick.
Zero sig->cputimer_expires in stop_process_timers().
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Cc: Spencer Candland <spencer@bluehost.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | kernel/posix-cpu-timers.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 438ff4523513..edec25a68e9e 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -1060,9 +1060,9 @@ static void check_thread_timers(struct task_struct *tsk, | |||
1060 | } | 1060 | } |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | static void stop_process_timers(struct task_struct *tsk) | 1063 | static void stop_process_timers(struct signal_struct *sig) |
1064 | { | 1064 | { |
1065 | struct thread_group_cputimer *cputimer = &tsk->signal->cputimer; | 1065 | struct thread_group_cputimer *cputimer = &sig->cputimer; |
1066 | unsigned long flags; | 1066 | unsigned long flags; |
1067 | 1067 | ||
1068 | if (!cputimer->running) | 1068 | if (!cputimer->running) |
@@ -1071,6 +1071,10 @@ static void stop_process_timers(struct task_struct *tsk) | |||
1071 | spin_lock_irqsave(&cputimer->lock, flags); | 1071 | spin_lock_irqsave(&cputimer->lock, flags); |
1072 | cputimer->running = 0; | 1072 | cputimer->running = 0; |
1073 | spin_unlock_irqrestore(&cputimer->lock, flags); | 1073 | spin_unlock_irqrestore(&cputimer->lock, flags); |
1074 | |||
1075 | sig->cputime_expires.prof_exp = cputime_zero; | ||
1076 | sig->cputime_expires.virt_exp = cputime_zero; | ||
1077 | sig->cputime_expires.sched_exp = 0; | ||
1074 | } | 1078 | } |
1075 | 1079 | ||
1076 | static u32 onecputick; | 1080 | static u32 onecputick; |
@@ -1131,7 +1135,7 @@ static void check_process_timers(struct task_struct *tsk, | |||
1131 | list_empty(&timers[CPUCLOCK_VIRT]) && | 1135 | list_empty(&timers[CPUCLOCK_VIRT]) && |
1132 | cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) && | 1136 | cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) && |
1133 | list_empty(&timers[CPUCLOCK_SCHED])) { | 1137 | list_empty(&timers[CPUCLOCK_SCHED])) { |
1134 | stop_process_timers(tsk); | 1138 | stop_process_timers(sig); |
1135 | return; | 1139 | return; |
1136 | } | 1140 | } |
1137 | 1141 | ||