aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 15:55:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 15:55:01 -0400
commitecc8b655b38a880b578146895e0e1e2d477ca2c0 (patch)
tree4acce96bac00909fa9472f0c0669714243ea5bee /kernel
parent2528ce3237be4e900f5eaa455490146e1422e424 (diff)
parente338125b8a886923ba8367207c144764dc352584 (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.c2
-rw-r--r--kernel/time/tick-sched.c12
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 */
198void tick_nohz_stop_sched_tick(void) 198void 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 */