aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Dugue <sebastien.dugue@bull.net>2008-12-01 08:09:07 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-30 01:37:19 -0500
commit5762ba1873b0bb9faa631aaa02f533c2b9837f82 (patch)
tree3ea61b03a12ec16620f8527c4c83cb90d80cf6cc
parent0ce74d9296c971b2355c26984ad0bc538e34dd6c (diff)
hrtimers: allow the hot-unplugging of all cpus
Impact: fix CPU hotplug hang on Power6 testbox On architectures that support offlining all cpus (at least powerpc/pseries), hot-unpluging the tick_do_timer_cpu can result in a system hang. This comes from the fact that if the cpu going down happens to be the cpu doing the tick, then as the tick_do_timer_cpu handover happens after the cpu is dead (via the CPU_DEAD notification), we're left without ticks, jiffies are frozen and any task relying on timers (msleep, ...) is stuck. That's particularly the case for the cpu looping in __cpu_die() waiting for the dying cpu to be dead. This patch addresses this by having the tick_do_timer_cpu handover happen earlier during the CPU_DYING notification. For this, a new clockevent notification type is introduced (CLOCK_EVT_NOTIFY_CPU_DYING) which is triggered in hrtimer_cpu_notify(). Signed-off-by: Sebastien Dugue <sebastien.dugue@bull.net> Cc: <stable@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/clockchips.h1
-rw-r--r--kernel/hrtimer.c4
-rw-r--r--kernel/time/tick-common.c26
3 files changed, 24 insertions, 7 deletions
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index ed3a5d473e52..c6de413c5dd1 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -36,6 +36,7 @@ enum clock_event_nofitiers {
36 CLOCK_EVT_NOTIFY_BROADCAST_EXIT, 36 CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
37 CLOCK_EVT_NOTIFY_SUSPEND, 37 CLOCK_EVT_NOTIFY_SUSPEND,
38 CLOCK_EVT_NOTIFY_RESUME, 38 CLOCK_EVT_NOTIFY_RESUME,
39 CLOCK_EVT_NOTIFY_CPU_DYING,
39 CLOCK_EVT_NOTIFY_CPU_DEAD, 40 CLOCK_EVT_NOTIFY_CPU_DEAD,
40}; 41};
41 42
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index c2a69b89ac61..61cb933395ba 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1609,6 +1609,10 @@ static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,
1609 break; 1609 break;
1610 1610
1611#ifdef CONFIG_HOTPLUG_CPU 1611#ifdef CONFIG_HOTPLUG_CPU
1612 case CPU_DYING:
1613 case CPU_DYING_FROZEN:
1614 clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
1615 break;
1612 case CPU_DEAD: 1616 case CPU_DEAD:
1613 case CPU_DEAD_FROZEN: 1617 case CPU_DEAD_FROZEN:
1614 { 1618 {
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index df12434b43ca..457d281258ee 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -274,6 +274,21 @@ out_bc:
274} 274}
275 275
276/* 276/*
277 * Transfer the do_timer job away from a dying cpu.
278 *
279 * Called with interrupts disabled.
280 */
281static void tick_handover_do_timer(int *cpup)
282{
283 if (*cpup == tick_do_timer_cpu) {
284 int cpu = first_cpu(cpu_online_map);
285
286 tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu :
287 TICK_DO_TIMER_NONE;
288 }
289}
290
291/*
277 * Shutdown an event device on a given cpu: 292 * Shutdown an event device on a given cpu:
278 * 293 *
279 * This is called on a life CPU, when a CPU is dead. So we cannot 294 * This is called on a life CPU, when a CPU is dead. So we cannot
@@ -297,13 +312,6 @@ static void tick_shutdown(unsigned int *cpup)
297 clockevents_exchange_device(dev, NULL); 312 clockevents_exchange_device(dev, NULL);
298 td->evtdev = NULL; 313 td->evtdev = NULL;
299 } 314 }
300 /* Transfer the do_timer job away from this cpu */
301 if (*cpup == tick_do_timer_cpu) {
302 int cpu = first_cpu(cpu_online_map);
303
304 tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu :
305 TICK_DO_TIMER_NONE;
306 }
307 spin_unlock_irqrestore(&tick_device_lock, flags); 315 spin_unlock_irqrestore(&tick_device_lock, flags);
308} 316}
309 317
@@ -357,6 +365,10 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
357 tick_broadcast_oneshot_control(reason); 365 tick_broadcast_oneshot_control(reason);
358 break; 366 break;
359 367
368 case CLOCK_EVT_NOTIFY_CPU_DYING:
369 tick_handover_do_timer(dev);
370 break;
371
360 case CLOCK_EVT_NOTIFY_CPU_DEAD: 372 case CLOCK_EVT_NOTIFY_CPU_DEAD:
361 tick_shutdown_broadcast_oneshot(dev); 373 tick_shutdown_broadcast_oneshot(dev);
362 tick_shutdown_broadcast(dev); 374 tick_shutdown_broadcast(dev);