sched/fair: filter energy_diff() based on energy_payoff value

Once the SchedTune support is enabled and the CPU bandwidth demand of a
task is boosted, we could expect increased energy consumptions which are
balanced by corresponding increases of tasks performance.
However, the current implementation of the energy_diff() function
accepts all and _only_ the schedule candidates which results into a
reduced expected system energy, which works against the boosting
strategy.

This patch links the energy_diff() function with the "energy payoff"
engine provided by SchedTune. The energy variation computed by the
energy_diff() function is now filtered using the SchedTune support to
evaluated the energy payoff for a boosted task.

With that patch, the energy_diff() function is going to reported as
"acceptable schedule candidate" only the schedule candidate which
corresponds to a positive energy_payoff.

Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>
This commit is contained in:
Patrick Bellasi
2016-01-15 15:48:03 +00:00
committed by Leo Yan
parent 637ee3715a
commit a2a6dc7508

View File

@@ -4706,9 +4706,12 @@ struct energy_env {
int src_cpu;
int dst_cpu;
int energy;
int payoff;
struct task_struct *task;
struct {
int before;
int after;
int delta;
int diff;
} nrg;
struct {
@@ -4929,6 +4932,44 @@ static inline bool cpu_in_sg(struct sched_group *sg, int cpu)
return cpu != -1 && cpumask_test_cpu(cpu, sched_group_cpus(sg));
}
#ifdef CONFIG_SCHED_TUNE
static int energy_diff_evaluate(struct energy_env *eenv)
{
unsigned int boost;
int nrg_delta;
/* Return energy diff when boost margin is 0 */
#ifdef CONFIG_CGROUP_SCHEDTUNE
boost = schedtune_task_boost(eenv->task);
#else
boost = get_sysctl_sched_cfs_boost();
#endif
if (boost == 0)
return eenv->nrg.diff;
/* Compute normalized energy diff */
nrg_delta = schedtune_normalize_energy(eenv->nrg.diff);
eenv->nrg.delta = nrg_delta;
eenv->payoff = schedtune_accept_deltas(
eenv->nrg.delta,
eenv->cap.delta,
eenv->task);
/*
* When SchedTune is enabled, the energy_diff() function will return
* the computed energy payoff value. Since the energy_diff() return
* value is expected to be negative by its callers, this evaluation
* function return a negative value each time the evaluation return a
* positive payoff, which is the condition for the acceptance of
* a scheduling decision
*/
return -eenv->payoff;
}
#else /* CONFIG_SCHED_TUNE */
#define energy_diff_evaluate(eenv) eenv->nrg.diff
#endif
/*
* energy_diff(): Estimate the energy impact of changing the utilization
* distribution. eenv specifies the change: utilisation amount, source, and
@@ -4946,7 +4987,7 @@ static int energy_diff(struct energy_env *eenv)
.util_delta = 0,
.src_cpu = eenv->src_cpu,
.dst_cpu = eenv->dst_cpu,
.nrg = { 0, 0, 0 },
.nrg = { 0, 0, 0, 0},
.cap = { 0, 0, 0 },
};
@@ -4982,8 +5023,9 @@ static int energy_diff(struct energy_env *eenv)
eenv->nrg.before = energy_before;
eenv->nrg.after = energy_after;
eenv->nrg.diff = eenv->nrg.after - eenv->nrg.before;
eenv->payoff = 0;
return eenv->nrg.diff;
return energy_diff_evaluate(eenv);
}
/*
@@ -5481,6 +5523,7 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target)
.util_delta = task_util(p),
.src_cpu = task_cpu(p),
.dst_cpu = target_cpu,
.task = p,
};
/* Not enough spare capacity on previous cpu */