Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17878012 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "timer: Don't wait for running timers when migrating during isolation"

parents befd2423 4142e308
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#include <linux/sched/deadline.h>
#include <linux/timer.h>
#include <linux/freezer.h>
#include <linux/delay.h>

#include <asm/uaccess.h>

@@ -1648,6 +1649,12 @@ static void migrate_hrtimer_list(struct hrtimer_cpu_base *old_base,
				raw_spin_unlock(&old_base->lock);
				raw_spin_unlock(&new_base->lock);
				cpu_relax();
				/*
				 * cpu_relax may just be a barrier. Grant the
				 * run_hrtimer_list code some time to obtain the
				 * spinlock.
				 */
				udelay(2);
				raw_spin_lock(&new_base->lock);
				raw_spin_lock_nested(&old_base->lock,
							SINGLE_DEPTH_NESTING);
+10 −14
Original line number Diff line number Diff line
@@ -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,