sched/fair: filter energy_diff() based on energy_payoff value
authorPatrick Bellasi <patrick.bellasi@arm.com>
Fri, 15 Jan 2016 15:48:03 +0000 (15:48 +0000)
committerPunit Agrawal <punit.agrawal@arm.com>
Mon, 21 Mar 2016 14:57:37 +0000 (14:57 +0000)
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>
kernel/sched/fair.c

index 3b80ad01aa8b64ceb54609c04f41a9871c07ddd8..1191c4b1b119b6cf12e40c7feb959b7de74117ca 100644 (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 */