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

Commit 39c8206a authored by Srivatsa Vaddagiri's avatar Srivatsa Vaddagiri Committed by Stephen Boyd
Browse files

sched: fix rq->lock recursion



Enabling SCHED_HRTICK currently results in rq->lock recursion and a hard
hang at bootup.  Essentially try_to_wakeup() grabs rq->lock and tries
arming a hrtimer via hrtimer_restart(), which deep down tries waking up
ksoftirqd, which leads to a recursive call to try_to_wakeup() and thus
attempt to take rq->lock recursively!!

This is fixed by having scheduler queue hrtimer via
__hrtimer_start_range_ns() which avoids waking up ksoftirqd.

Signed-off-by: default avatarSrivatsa Vaddagiri <vatsa@codeaurora.org>
Change-Id: I11a13be1d9db3a749614ccf3d4f5fb7bf6f18fa1
(cherry picked from commit 4ca1d04ea0bdc225cc7db302172f3375a63f44de)
parent 471182d7
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -410,9 +410,16 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer)
static void __hrtick_start(void *arg)
{
	struct rq *rq = arg;
	struct hrtimer *timer = &rq->hrtick_timer;
	ktime_t soft, hard;
	unsigned long delta;

	soft = hrtimer_get_softexpires(timer);
	hard = hrtimer_get_expires(timer);
	delta = ktime_to_ns(ktime_sub(hard, soft));

	raw_spin_lock(&rq->lock);
	hrtimer_restart(&rq->hrtick_timer);
	__hrtimer_start_range_ns(timer, soft, delta, HRTIMER_MODE_ABS, 0);
	rq->hrtick_csd_pending = 0;
	raw_spin_unlock(&rq->lock);
}
@@ -430,7 +437,8 @@ void hrtick_start(struct rq *rq, u64 delay)
	hrtimer_set_expires(timer, time);

	if (rq == this_rq()) {
		hrtimer_restart(timer);
		__hrtimer_start_range_ns(timer, ns_to_ktime(delay), 0,
						 HRTIMER_MODE_REL_PINNED, 0);
	} else if (!rq->hrtick_csd_pending) {
		__smp_call_function_single(cpu_of(rq), &rq->hrtick_csd, 0);
		rq->hrtick_csd_pending = 1;