diff --git a/[refs] b/[refs] index aa0bdb106649..fdc2741a6c49 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c9819f4593e8d052b41a89f47140f5c5e7e30582 +refs/heads/master: 1bd77f2da58e9cdd1f159217887343dadd9af417 diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 0a3e748d737d..0a4a26b21f69 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -2774,14 +2774,28 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd) static void idle_balance(int this_cpu, struct rq *this_rq) { struct sched_domain *sd; + int pulled_task = 0; + unsigned long next_balance = jiffies + 60 * HZ; for_each_domain(this_cpu, sd) { if (sd->flags & SD_BALANCE_NEWIDLE) { /* If we've pulled tasks over stop searching: */ - if (load_balance_newidle(this_cpu, this_rq, sd)) + pulled_task = load_balance_newidle(this_cpu, + this_rq, sd); + if (time_after(next_balance, + sd->last_balance + sd->balance_interval)) + next_balance = sd->last_balance + + sd->balance_interval; + if (pulled_task) break; } } + if (!pulled_task) + /* + * We are going idle. next_balance may be set based on + * a busy processor. So reset next_balance. + */ + this_rq->next_balance = next_balance; } /* @@ -2904,7 +2918,7 @@ static void run_rebalance_domains(struct softirq_action *h) */ idle = NOT_IDLE; } - sd->last_balance += interval; + sd->last_balance = jiffies; } if (time_after(next_balance, sd->last_balance + interval)) next_balance = sd->last_balance + interval;