Commit 92c4ca5c authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds

sched: fix next_interval determination in idle_balance()

The intervals of domains that do not have SD_BALANCE_NEWIDLE must be
considered for the calculation of the time of the next balance.  Otherwise
we may defer rebalancing forever.

Siddha also spotted that the conversion of the balance interval
to jiffies is missing. Fix that to.

From: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>

also continue the loop if !(sd->flags & SD_LOAD_BALANCE).
Tested-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>

It did in fact trigger under all three of mainline, CFS, and -rt including CFS
-- see below for a couple of emails from last Friday giving results for these
three on the AMD box (where it happened) and on a single-quad NUMA-Q system
(where it did not, at least not with such severity).
Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Cc: <stable@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 84966343
...@@ -2938,17 +2938,21 @@ static void idle_balance(int this_cpu, struct rq *this_rq) ...@@ -2938,17 +2938,21 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
unsigned long next_balance = jiffies + 60 * HZ; unsigned long next_balance = jiffies + 60 * HZ;
for_each_domain(this_cpu, sd) { for_each_domain(this_cpu, sd) {
if (sd->flags & SD_BALANCE_NEWIDLE) { unsigned long interval;
if (!(sd->flags & SD_LOAD_BALANCE))
continue;
if (sd->flags & SD_BALANCE_NEWIDLE)
/* If we've pulled tasks over stop searching: */ /* If we've pulled tasks over stop searching: */
pulled_task = load_balance_newidle(this_cpu, pulled_task = load_balance_newidle(this_cpu,
this_rq, sd); this_rq, sd);
if (time_after(next_balance,
sd->last_balance + sd->balance_interval)) interval = msecs_to_jiffies(sd->balance_interval);
next_balance = sd->last_balance if (time_after(next_balance, sd->last_balance + interval))
+ sd->balance_interval; next_balance = sd->last_balance + interval;
if (pulled_task) if (pulled_task)
break; break;
}
} }
if (!pulled_task) if (!pulled_task)
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment