From e07be07dcbbd5b0e2b8d2686a2bbbd8198c158fd Mon Sep 17 00:00:00 2001 From: Sebastien Dugue Date: Mon, 1 Dec 2008 14:09:07 +0100 Subject: [PATCH] --- yaml --- r: 135732 b: refs/heads/master c: 5762ba1873b0bb9faa631aaa02f533c2b9837f82 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/clockchips.h | 1 + trunk/kernel/hrtimer.c | 4 ++++ trunk/kernel/time/tick-common.c | 26 +++++++++++++++++++------- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index ba64f31a3aa6..9a06e449f5ab 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0ce74d9296c971b2355c26984ad0bc538e34dd6c +refs/heads/master: 5762ba1873b0bb9faa631aaa02f533c2b9837f82 diff --git a/trunk/include/linux/clockchips.h b/trunk/include/linux/clockchips.h index ed3a5d473e52..c6de413c5dd1 100644 --- a/trunk/include/linux/clockchips.h +++ b/trunk/include/linux/clockchips.h @@ -36,6 +36,7 @@ enum clock_event_nofitiers { CLOCK_EVT_NOTIFY_BROADCAST_EXIT, CLOCK_EVT_NOTIFY_SUSPEND, CLOCK_EVT_NOTIFY_RESUME, + CLOCK_EVT_NOTIFY_CPU_DYING, CLOCK_EVT_NOTIFY_CPU_DEAD, }; diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index c2a69b89ac61..61cb933395ba 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -1609,6 +1609,10 @@ static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self, break; #ifdef CONFIG_HOTPLUG_CPU + case CPU_DYING: + case CPU_DYING_FROZEN: + clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu); + break; case CPU_DEAD: case CPU_DEAD_FROZEN: { diff --git a/trunk/kernel/time/tick-common.c b/trunk/kernel/time/tick-common.c index df12434b43ca..457d281258ee 100644 --- a/trunk/kernel/time/tick-common.c +++ b/trunk/kernel/time/tick-common.c @@ -273,6 +273,21 @@ static int tick_check_new_device(struct clock_event_device *newdev) return ret; } +/* + * Transfer the do_timer job away from a dying cpu. + * + * Called with interrupts disabled. + */ +static void tick_handover_do_timer(int *cpup) +{ + if (*cpup == tick_do_timer_cpu) { + int cpu = first_cpu(cpu_online_map); + + tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : + TICK_DO_TIMER_NONE; + } +} + /* * Shutdown an event device on a given cpu: * @@ -297,13 +312,6 @@ static void tick_shutdown(unsigned int *cpup) clockevents_exchange_device(dev, NULL); td->evtdev = NULL; } - /* Transfer the do_timer job away from this cpu */ - if (*cpup == tick_do_timer_cpu) { - int cpu = first_cpu(cpu_online_map); - - tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : - TICK_DO_TIMER_NONE; - } spin_unlock_irqrestore(&tick_device_lock, flags); } @@ -357,6 +365,10 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason, tick_broadcast_oneshot_control(reason); break; + case CLOCK_EVT_NOTIFY_CPU_DYING: + tick_handover_do_timer(dev); + break; + case CLOCK_EVT_NOTIFY_CPU_DEAD: tick_shutdown_broadcast_oneshot(dev); tick_shutdown_broadcast(dev);