Commit 674134b9 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Thomas Gleixner

sched: cleanup wake_idle power saving

Hopefully a more readable version of the same.
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarDinakar Guniguntala <dino@in.ibm.com>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Darren Hart <dvhltc@us.ibm.com>
Cc: John Kacur <jkacur@redhat.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent d65d153b
...@@ -1040,6 +1040,41 @@ static void yield_task_fair(struct rq *rq) ...@@ -1040,6 +1040,41 @@ static void yield_task_fair(struct rq *rq)
se->vruntime = rightmost->vruntime + 1; se->vruntime = rightmost->vruntime + 1;
} }
#if defined(ARCH_HAS_SCHED_WAKE_IDLE)
/*
* At POWERSAVINGS_BALANCE_WAKEUP level, if both this_cpu and prev_cpu
* are idle and this is not a kernel thread and this task's affinity
* allows it to be moved to preferred cpu, then just move!
*
* XXX - can generate significant overload on perferred_wakeup_cpu
* with plenty of idle cpus, leading to a significant loss in
* throughput.
*
* Returns: < 0 - no placement decision made
* >= 0 - place on cpu
*/
static int wake_idle_power_save(int cpu, struct task_struct *p)
{
int this_cpu = smp_processor_id();
int wakeup_cpu;
if (sched_mc_power_savings < POWERSAVINGS_BALANCE_WAKEUP)
return -1;
if (!idle_cpu(cpu) || !idle_cpu(this_cpu))
return -1;
if (!p->mm || (p->flags & PF_KTHREAD))
return -1;
wakeup_cpu = cpu_rq(this_cpu)->rd->sched_mc_preferred_wakeup_cpu;
if (!cpu_isset(wakeup_cpu, p->cpus_allowed))
return -1;
return wakeup_cpu;
}
/* /*
* wake_idle() will wake a task on an idle cpu if task->cpu is * wake_idle() will wake a task on an idle cpu if task->cpu is
* not idle and an idle cpu is available. The span of cpus to * not idle and an idle cpu is available. The span of cpus to
...@@ -1050,29 +1085,14 @@ static void yield_task_fair(struct rq *rq) ...@@ -1050,29 +1085,14 @@ static void yield_task_fair(struct rq *rq)
* *
* Returns the CPU we should wake onto. * Returns the CPU we should wake onto.
*/ */
#if defined(ARCH_HAS_SCHED_WAKE_IDLE)
static int wake_idle(int cpu, struct task_struct *p) static int wake_idle(int cpu, struct task_struct *p)
{ {
struct sched_domain *sd; struct sched_domain *sd;
int i; int i;
unsigned int chosen_wakeup_cpu;
int this_cpu;
/*
* At POWERSAVINGS_BALANCE_WAKEUP level, if both this_cpu and prev_cpu
* are idle and this is not a kernel thread and this task's affinity
* allows it to be moved to preferred cpu, then just move!
*/
this_cpu = smp_processor_id();
chosen_wakeup_cpu =
cpu_rq(this_cpu)->rd->sched_mc_preferred_wakeup_cpu;
if (sched_mc_power_savings >= POWERSAVINGS_BALANCE_WAKEUP && i = wake_idle_power_save(cpu, p);
idle_cpu(cpu) && idle_cpu(this_cpu) && if (i >= 0)
p->mm && !(p->flags & PF_KTHREAD) && return i;
cpu_isset(chosen_wakeup_cpu, p->cpus_allowed))
return chosen_wakeup_cpu;
/* /*
* If it is idle, then it is the best cpu to run this task. * If it is idle, then it is the best cpu to run this task.
...@@ -1081,7 +1101,7 @@ static int wake_idle(int cpu, struct task_struct *p) ...@@ -1081,7 +1101,7 @@ static int wake_idle(int cpu, struct task_struct *p)
* Siblings must be also busy(in most cases) as they didn't already * Siblings must be also busy(in most cases) as they didn't already
* pickup the extra load from this cpu and hence we need not check * pickup the extra load from this cpu and hence we need not check
* sibling runqueue info. This will avoid the checks and cache miss * sibling runqueue info. This will avoid the checks and cache miss
* penalities associated with that. * penalties associated with that.
*/ */
if (idle_cpu(cpu) || cpu_rq(cpu)->cfs.nr_running > 1) if (idle_cpu(cpu) || cpu_rq(cpu)->cfs.nr_running > 1)
return cpu; return cpu;
......
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