summaryrefslogtreecommitdiff
path: root/kernel/time/timer.c
diff options
context:
space:
mode:
authorOlav Haugan <ohaugan@codeaurora.org>2016-07-08 10:59:08 -0700
committerOlav Haugan <ohaugan@codeaurora.org>2016-09-20 17:47:11 -0700
commit6cc98f03adbf517986a90c43af0cbc9a732b8435 (patch)
treee1c7a461514e2d0e1495d3b0dff596828f376af9 /kernel/time/timer.c
parent9e2d528dc47d04e98c5e6f1c4ef84fc268115d36 (diff)
timer: Ensure timers are not running before migrating
This is needed to support migration of timers during cpu isolation. A timer might be running on the CPU that we want to isolate so we are unable to migrate the timers at this point. We are adding a spin-loop to wait for the timer to finish before migrating the timers. Change-Id: I24d6e91b6dff468c640c2fe3a37a7f31b6f0c79a Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
Diffstat (limited to 'kernel/time/timer.c')
-rw-r--r--kernel/time/timer.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 51896272fcde..be750f6b2a68 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1635,7 +1635,7 @@ static void migrate_timer_list(struct tvec_base *new_base, struct hlist_head *he
}
}
-static void migrate_timers(int cpu)
+static void migrate_timers(int cpu, bool wait)
{
struct tvec_base *old_base;
struct tvec_base *new_base;
@@ -1651,7 +1651,18 @@ static void migrate_timers(int cpu)
spin_lock_irq(&new_base->lock);
spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
- BUG_ON(old_base->running_timer);
+ if (wait) {
+ /* Ensure timers are done running before continuing */
+ while (old_base->running_timer) {
+ spin_unlock(&old_base->lock);
+ spin_unlock_irq(&new_base->lock);
+ cpu_relax();
+ spin_lock_irq(&new_base->lock);
+ spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
+ }
+ } else {
+ BUG_ON(old_base->running_timer);
+ }
for (i = 0; i < TVR_SIZE; i++)
migrate_timer_list(new_base, old_base->tv1.vec + i);
@@ -1676,7 +1687,7 @@ static int timer_cpu_notify(struct notifier_block *self,
switch (action) {
case CPU_DEAD:
case CPU_DEAD_FROZEN:
- migrate_timers((long)hcpu);
+ migrate_timers((long)hcpu, false);
break;
default:
break;