Commit 0e5b5337f0da073e1f17aec3c322ea7826975d0d
Committed by
Ingo Molnar
1 parent
6ccdc84b81
Exists in
ti-lsk-linux-4.1.y
and in
12 other branches
sched: Fix updating rq->max_idle_balance_cost and rq->next_balance in idle_balance()
The following commit: e5fc66119ec9 ("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: Jason Low <jason.low2@hp.com> Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com> Signed-off-by: Peter 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: Ingo Molnar <mingo@kernel.org>
Showing 1 changed file with 8 additions and 8 deletions Side-by-side Diff
kernel/sched/fair.c
... | ... | @@ -6653,6 +6653,7 @@ |
6653 | 6653 | int this_cpu = this_rq->cpu; |
6654 | 6654 | |
6655 | 6655 | idle_enter_fair(this_rq); |
6656 | + | |
6656 | 6657 | /* |
6657 | 6658 | * We must set idle_stamp _before_ calling idle_balance(), such that we |
6658 | 6659 | * measure the duration of idle_balance() as idle time. |
6659 | 6660 | |
6660 | 6661 | |
6661 | 6662 | |
... | ... | @@ -6705,14 +6706,16 @@ |
6705 | 6706 | |
6706 | 6707 | raw_spin_lock(&this_rq->lock); |
6707 | 6708 | |
6709 | + if (curr_cost > this_rq->max_idle_balance_cost) | |
6710 | + this_rq->max_idle_balance_cost = curr_cost; | |
6711 | + | |
6708 | 6712 | /* |
6709 | - * While browsing the domains, we released the rq lock. | |
6710 | - * A task could have be enqueued in the meantime | |
6713 | + * While browsing the domains, we released the rq lock, a task could | |
6714 | + * have been enqueued in the meantime. Since we're not going idle, | |
6715 | + * pretend we pulled a task. | |
6711 | 6716 | */ |
6712 | - if (this_rq->cfs.h_nr_running && !pulled_task) { | |
6717 | + if (this_rq->cfs.h_nr_running && !pulled_task) | |
6713 | 6718 | pulled_task = 1; |
6714 | - goto out; | |
6715 | - } | |
6716 | 6719 | |
6717 | 6720 | if (pulled_task || time_after(jiffies, this_rq->next_balance)) { |
6718 | 6721 | /* |
... | ... | @@ -6721,9 +6724,6 @@ |
6721 | 6724 | */ |
6722 | 6725 | this_rq->next_balance = next_balance; |
6723 | 6726 | } |
6724 | - | |
6725 | - if (curr_cost > this_rq->max_idle_balance_cost) | |
6726 | - this_rq->max_idle_balance_cost = curr_cost; | |
6727 | 6727 | |
6728 | 6728 | out: |
6729 | 6729 | /* Is there a task of a high priority class? */ |