diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 15:55:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 15:55:01 -0400 |
commit | ecc8b655b38a880b578146895e0e1e2d477ca2c0 (patch) | |
tree | 4acce96bac00909fa9472f0c0669714243ea5bee /kernel | |
parent | 2528ce3237be4e900f5eaa455490146e1422e424 (diff) | |
parent | e338125b8a886923ba8367207c144764dc352584 (diff) |
Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
nohz: adjust tick_nohz_stop_sched_tick() call of s390 as well
nohz: prevent tick stop outside of the idle loop
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/softirq.c | 2 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 12 |
2 files changed, 11 insertions, 3 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c index 81e2fe0f983a..f6b03d56c2bf 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -286,7 +286,7 @@ void irq_exit(void) | |||
286 | #ifdef CONFIG_NO_HZ | 286 | #ifdef CONFIG_NO_HZ |
287 | /* Make sure that timer wheel updates are propagated */ | 287 | /* Make sure that timer wheel updates are propagated */ |
288 | if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched()) | 288 | if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched()) |
289 | tick_nohz_stop_sched_tick(); | 289 | tick_nohz_stop_sched_tick(0); |
290 | rcu_irq_exit(); | 290 | rcu_irq_exit(); |
291 | #endif | 291 | #endif |
292 | preempt_enable_no_resched(); | 292 | preempt_enable_no_resched(); |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 942fc7c85283..825b4c00fe44 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -195,7 +195,7 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) | |||
195 | * Called either from the idle loop or from irq_exit() when an idle period was | 195 | * Called either from the idle loop or from irq_exit() when an idle period was |
196 | * just interrupted by an interrupt which did not cause a reschedule. | 196 | * just interrupted by an interrupt which did not cause a reschedule. |
197 | */ | 197 | */ |
198 | void tick_nohz_stop_sched_tick(void) | 198 | void tick_nohz_stop_sched_tick(int inidle) |
199 | { | 199 | { |
200 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags; | 200 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags; |
201 | struct tick_sched *ts; | 201 | struct tick_sched *ts; |
@@ -224,6 +224,11 @@ void tick_nohz_stop_sched_tick(void) | |||
224 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) | 224 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) |
225 | goto end; | 225 | goto end; |
226 | 226 | ||
227 | if (!inidle && !ts->inidle) | ||
228 | goto end; | ||
229 | |||
230 | ts->inidle = 1; | ||
231 | |||
227 | if (need_resched()) | 232 | if (need_resched()) |
228 | goto end; | 233 | goto end; |
229 | 234 | ||
@@ -373,11 +378,14 @@ void tick_nohz_restart_sched_tick(void) | |||
373 | local_irq_disable(); | 378 | local_irq_disable(); |
374 | tick_nohz_stop_idle(cpu); | 379 | tick_nohz_stop_idle(cpu); |
375 | 380 | ||
376 | if (!ts->tick_stopped) { | 381 | if (!ts->inidle || !ts->tick_stopped) { |
382 | ts->inidle = 0; | ||
377 | local_irq_enable(); | 383 | local_irq_enable(); |
378 | return; | 384 | return; |
379 | } | 385 | } |
380 | 386 | ||
387 | ts->inidle = 0; | ||
388 | |||
381 | rcu_exit_nohz(); | 389 | rcu_exit_nohz(); |
382 | 390 | ||
383 | /* Update jiffies first */ | 391 | /* Update jiffies first */ |