summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorSrivatsa Vaddagiri <vatsa@codeaurora.org>2014-12-17 12:06:08 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:01:25 -0700
commitee87e1d7c4da8b805a896003e9fede85b2b4074f (patch)
treefcd230d8b257ff5dc5fa6707dd09d41f8c76164c /kernel
parent3f947e7ba7a22de8b5be7b064acbb3d395aa2760 (diff)
sched: Consider PF_WAKE_UP_IDLE in select_best_cpu()
sysctl_sched_prefer_idle controls selection of idle cpus for waking tasks. In some cases, waking to idle cpus help performance while in other cases it hurts (as tasks incur latency associated with C-state wakeup). Its ideal if scheduler can adapt prefer_idle behavior based on the task that is waking up, but that's hard for scheduler to figure by itself. PF_WAKE_UP_IDLE hint can be provided by external module/driver in such case to guide scheduler in preferring an idle cpu for select tasks irrespective of sysctl_sched_prefer_idle flag. This patch enhances select_best_cpu() to consider PF_WAKE_UP_IDLE hint. Wakeup posted from any task that has PF_WAKE_UP_IDLE set is a hint for scheduler to prefer idle cpu for waking tasks. Similarly scheduler will attempt to place any task with PF_WAKE_UP_IDLE set on idle cpu when they wakeup. CRs-Fixed: 773101 Change-Id: Ia8bf334d98fd9fd2ff9eda875430497d55d64ce6 Signed-off-by: Srivatsa Vaddagiri <vatsa@codeaurora.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/fair.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index d9d4694d58da..4260cb552d9f 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3230,6 +3230,20 @@ static int select_packing_target(struct task_struct *p, int best_cpu)
return target;
}
+/*
+ * Should task be woken to any available idle cpu?
+ *
+ * Waking tasks to idle cpu has mixed implications on both performance and
+ * power. In many cases, scheduler can't estimate correctly impact of using idle
+ * cpus on either performance or power. PF_WAKE_UP_IDLE allows external kernel
+ * module to pass a strong hint to scheduler that the task in question should be
+ * woken to idle cpu, generally to improve performance.
+ */
+static inline int wake_to_idle(struct task_struct *p)
+{
+ return (current->flags & PF_WAKE_UP_IDLE) ||
+ (p->flags & PF_WAKE_UP_IDLE);
+}
/* return cheapest cpu that can fit this task */
static int select_best_cpu(struct task_struct *p, int target, int reason,
@@ -3245,6 +3259,13 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
int cstate, min_cstate = INT_MAX;
int prefer_idle = reason ? 1 : sysctl_sched_prefer_idle;
int curr_cpu = smp_processor_id();
+ int prefer_idle_override = 0;
+
+ if (wake_to_idle(p)) {
+ prefer_idle = 1;
+ prefer_idle_override = 1;
+ small_task = 0;
+ }
trace_sched_task_load(p, small_task, boost, reason, sync, prefer_idle);
@@ -3377,7 +3398,7 @@ done:
best_cpu = fallback_idle_cpu;
}
- if (cpu_rq(best_cpu)->mostly_idle_freq)
+ if (cpu_rq(best_cpu)->mostly_idle_freq && !prefer_idle_override)
best_cpu = select_packing_target(p, best_cpu);
return best_cpu;