summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Muckle <smuckle@codeaurora.org>2014-12-10 13:22:11 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:01:16 -0700
commitd1b240ccc7317c502b8a051a7d94466de482f8a4 (patch)
treee38e57f1b9d39982280f3d163db7f6e9a965a849
parentb9c3d7384dc6df0697b0a4bbf0f1dfb855543e11 (diff)
sched: treat sync waker CPUs with 1 task as idle
When a CPU with one task performs a sync wakeup, its one task is expected to sleep immediately so this CPU should be treated as idle for the purposes of CPU selection for the waking task. This is only done when idle CPUs are the preferred targets for non-small task wakeups. When prefer_idle is 0, the CPU is left as non-idle in the selection logic so it is still a preferred candidate for the sync wakeup. Change-Id: I65c6535169293e8ba0c37fb5e88aec336338f7d7 Signed-off-by: Steve Muckle <smuckle@codeaurora.org>
-rw-r--r--kernel/sched/fair.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 613420b3836e..9ab83b5af025 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3228,6 +3228,7 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
int boost = sched_boost();
int cstate, min_cstate = INT_MAX;
int prefer_idle = reason ? 1 : sysctl_sched_prefer_idle;
+ int curr_cpu = smp_processor_id();
trace_sched_task_load(p, small_task, boost, reason, sync, prefer_idle);
@@ -3293,9 +3294,14 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
/*
* Partition CPUs based on whether they are completely idle
* or not. For completely idle CPUs we choose the one in
- * the lowest C-state and then break ties with power cost
+ * the lowest C-state and then break ties with power cost.
+ *
+ * For sync wakeups we only consider the waker CPU as idle if
+ * prefer_idle is set. Otherwise if prefer_idle is unset sync
+ * wakeups will get biased away from the waker CPU.
*/
- if (idle_cpu(i)) {
+ if (idle_cpu(i) || (sync && i == curr_cpu && prefer_idle &&
+ cpu_rq(i)->nr_running == 1)) {
if (cstate > min_cstate)
continue;