diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2007-09-16 09:36:43 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@chaos.(none)> | 2007-09-16 09:36:43 -0400 |
commit | 5e41d0d60a534d2a5dc9772600a58f44c8d12506 (patch) | |
tree | d020ec1e72c338f3bf9dc4558ac3c82527a02384 /kernel/time | |
parent | 31d9b3938c0459e5e9755ce0a98ac1e24eeff972 (diff) |
clockevents: prevent stale tick update on offline cpu
Taking a cpu offline removes the cpu from the online mask before the
CPU_DEAD notification is done. The clock events layer does the cleanup
of the dead CPU from the CPU_DEAD notifier chain. tick_do_timer_cpu is
used to avoid xtime lock contention by assigning the task of jiffies
xtime updates to one CPU. If a CPU is taken offline, then this
assignment becomes stale. This went unnoticed because most of the time
the offline CPU went dead before the online CPU reached __cpu_die(),
where the CPU_DEAD state is checked. In the case that the offline CPU did
not reach the DEAD state before we reach __cpu_die(), the code in there
goes to sleep for 100ms. Due to the stale time update assignment, the
system is stuck forever.
Take the assignment away when a cpu is not longer in the cpu_online_mask.
We do this in the last call to tick_nohz_stop_sched_tick() when the offline
CPU is on the way to the final play_dead() idle entry.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/tick-sched.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index b416995b9757..8c3fef1db09c 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -160,6 +160,18 @@ void tick_nohz_stop_sched_tick(void) | |||
160 | cpu = smp_processor_id(); | 160 | cpu = smp_processor_id(); |
161 | ts = &per_cpu(tick_cpu_sched, cpu); | 161 | ts = &per_cpu(tick_cpu_sched, cpu); |
162 | 162 | ||
163 | /* | ||
164 | * If this cpu is offline and it is the one which updates | ||
165 | * jiffies, then give up the assignment and let it be taken by | ||
166 | * the cpu which runs the tick timer next. If we don't drop | ||
167 | * this here the jiffies might be stale and do_timer() never | ||
168 | * invoked. | ||
169 | */ | ||
170 | if (unlikely(!cpu_online(cpu))) { | ||
171 | if (cpu == tick_do_timer_cpu) | ||
172 | tick_do_timer_cpu = -1; | ||
173 | } | ||
174 | |||
163 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) | 175 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) |
164 | goto end; | 176 | goto end; |
165 | 177 | ||