summaryrefslogtreecommitdiff
path: root/kernel/time/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/timer.c')
-rw-r--r--kernel/time/timer.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 748eefb72a91..5ebefc7cfa4f 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1640,7 +1640,7 @@ static void migrate_timer_list(struct tvec_base *new_base,
}
}
-static void __migrate_timers(int cpu, bool wait, bool remove_pinned)
+static void __migrate_timers(int cpu, bool remove_pinned)
{
struct tvec_base *old_base;
struct tvec_base *new_base;
@@ -1656,18 +1656,14 @@ static void __migrate_timers(int cpu, bool wait, bool remove_pinned)
spin_lock_irqsave(&new_base->lock, flags);
spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
- if (wait) {
- /* Ensure timers are done running before continuing */
- while (old_base->running_timer) {
- spin_unlock(&old_base->lock);
- spin_unlock_irqrestore(&new_base->lock, flags);
- cpu_relax();
- spin_lock_irqsave(&new_base->lock, flags);
- spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
- }
- } else {
+ /*
+ * If we're in the hotplug path, kill the system if there's a running
+ * timer. It's ok to have a running timer in the isolation case - the
+ * currently running or just expired timers are off of the timer wheel
+ * and so everything else can be migrated off.
+ */
+ if (!cpu_online(cpu))
BUG_ON(old_base->running_timer);
- }
for (i = 0; i < TVR_SIZE; i++)
migrate_timer_list(new_base, old_base->tv1.vec + i,
@@ -1692,12 +1688,12 @@ static void __migrate_timers(int cpu, bool wait, bool remove_pinned)
static void migrate_timers(int cpu)
{
BUG_ON(cpu_online(cpu));
- __migrate_timers(cpu, false, true);
+ __migrate_timers(cpu, true);
}
void timer_quiesce_cpu(void *cpup)
{
- __migrate_timers(*(int *)cpup, true, false);
+ __migrate_timers(*(int *)cpup, false);
}
static int timer_cpu_notify(struct notifier_block *self,