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

Commit 0e5b5337 authored by Jason Low's avatar Jason Low Committed by Ingo Molnar
Browse files

sched: Fix updating rq->max_idle_balance_cost and rq->next_balance in idle_balance()



The following commit:

  e5fc6611 ("sched: Fix race in idle_balance()")

can potentially cause rq->max_idle_balance_cost to not be updated,
even when load_balance(NEWLY_IDLE) is attempted and the per-sd
max cost value is updated.

Preeti noticed a similar issue with updating rq->next_balance.

In this patch, we fix this by making sure we still check/update those values
even if a task gets enqueued while browsing the domains.

Signed-off-by: default avatarJason Low <jason.low2@hp.com>
Reviewed-by: default avatarPreeti U Murthy <preeti@linux.vnet.ibm.com>
Signed-off-by: default avatarPeter Zijlstra <peterz@infradead.org>
Cc: morten.rasmussen@arm.com
Cc: aswin@hp.com
Cc: daniel.lezcano@linaro.org
Cc: alex.shi@linaro.org
Cc: efault@gmx.de
Cc: vincent.guittot@linaro.org
Link: http://lkml.kernel.org/r/1398725155-7591-2-git-send-email-jason.low2@hp.com


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 6ccdc84b
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -6653,6 +6653,7 @@ static int idle_balance(struct rq *this_rq)
	int this_cpu = this_rq->cpu;

	idle_enter_fair(this_rq);

	/*
	 * We must set idle_stamp _before_ calling idle_balance(), such that we
	 * measure the duration of idle_balance() as idle time.
@@ -6705,14 +6706,16 @@ static int idle_balance(struct rq *this_rq)

	raw_spin_lock(&this_rq->lock);

	if (curr_cost > this_rq->max_idle_balance_cost)
		this_rq->max_idle_balance_cost = curr_cost;

	/*
	 * While browsing the domains, we released the rq lock.
	 * A task could have be enqueued in the meantime
	 * While browsing the domains, we released the rq lock, a task could
	 * have been enqueued in the meantime. Since we're not going idle,
	 * pretend we pulled a task.
	 */
	if (this_rq->cfs.h_nr_running && !pulled_task) {
	if (this_rq->cfs.h_nr_running && !pulled_task)
		pulled_task = 1;
		goto out;
	}

	if (pulled_task || time_after(jiffies, this_rq->next_balance)) {
		/*
@@ -6722,9 +6725,6 @@ static int idle_balance(struct rq *this_rq)
		this_rq->next_balance = next_balance;
	}

	if (curr_cost > this_rq->max_idle_balance_cost)
		this_rq->max_idle_balance_cost = curr_cost;

out:
	/* Is there a task of a high priority class? */
	if (this_rq->nr_running != this_rq->cfs.h_nr_running &&