aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Perret <quentin.perret@arm.com>2018-12-03 04:56:26 -0500
committerIngo Molnar <mingo@kernel.org>2018-12-11 09:17:02 -0500
commit390031e4c309c94ecc07a558187eb5185200df83 (patch)
treea816211d82d16acc572030f0fe2f85160f16790b
parent2802bf3cd936fe2c8033a696d375a4d9d3974de4 (diff)
sched/fair: Introduce an energy estimation helper function
In preparation for the definition of an energy-aware wakeup path, introduce a helper function to estimate the consequence on system energy when a specific task wakes-up on a specific CPU. compute_energy() estimates the capacity state to be reached by all performance domains and estimates the consumption of each online CPU according to its Energy Model and its percentage of busy time. Signed-off-by: Quentin Perret <quentin.perret@arm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: adharmap@codeaurora.org Cc: chris.redpath@arm.com Cc: currojerez@riseup.net Cc: dietmar.eggemann@arm.com Cc: edubezval@gmail.com Cc: gregkh@linuxfoundation.org Cc: javi.merino@kernel.org Cc: joel@joelfernandes.org Cc: juri.lelli@redhat.com Cc: morten.rasmussen@arm.com Cc: patrick.bellasi@arm.com Cc: pkondeti@codeaurora.org Cc: rjw@rjwysocki.net Cc: skannan@codeaurora.org Cc: smuckle@google.com Cc: srinivas.pandruvada@linux.intel.com Cc: thara.gopinath@linaro.org Cc: tkjos@google.com Cc: valentin.schneider@arm.com Cc: vincent.guittot@linaro.org Cc: viresh.kumar@linaro.org Link: https://lkml.kernel.org/r/20181203095628.11858-14-quentin.perret@arm.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--kernel/sched/fair.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 767e7675774b..b3c94584d947 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -6378,6 +6378,82 @@ static int wake_cap(struct task_struct *p, int cpu, int prev_cpu)
6378} 6378}
6379 6379
6380/* 6380/*
6381 * Predicts what cpu_util(@cpu) would return if @p was migrated (and enqueued)
6382 * to @dst_cpu.
6383 */
6384static unsigned long cpu_util_next(int cpu, struct task_struct *p, int dst_cpu)
6385{
6386 struct cfs_rq *cfs_rq = &cpu_rq(cpu)->cfs;
6387 unsigned long util_est, util = READ_ONCE(cfs_rq->avg.util_avg);
6388
6389 /*
6390 * If @p migrates from @cpu to another, remove its contribution. Or,
6391 * if @p migrates from another CPU to @cpu, add its contribution. In
6392 * the other cases, @cpu is not impacted by the migration, so the
6393 * util_avg should already be correct.
6394 */
6395 if (task_cpu(p) == cpu && dst_cpu != cpu)
6396 sub_positive(&util, task_util(p));
6397 else if (task_cpu(p) != cpu && dst_cpu == cpu)
6398 util += task_util(p);
6399
6400 if (sched_feat(UTIL_EST)) {
6401 util_est = READ_ONCE(cfs_rq->avg.util_est.enqueued);
6402
6403 /*
6404 * During wake-up, the task isn't enqueued yet and doesn't
6405 * appear in the cfs_rq->avg.util_est.enqueued of any rq,
6406 * so just add it (if needed) to "simulate" what will be
6407 * cpu_util() after the task has been enqueued.
6408 */
6409 if (dst_cpu == cpu)
6410 util_est += _task_util_est(p);
6411
6412 util = max(util, util_est);
6413 }
6414
6415 return min(util, capacity_orig_of(cpu));
6416}
6417
6418/*
6419 * compute_energy(): Estimates the energy that would be consumed if @p was
6420 * migrated to @dst_cpu. compute_energy() predicts what will be the utilization
6421 * landscape of the * CPUs after the task migration, and uses the Energy Model
6422 * to compute what would be the energy if we decided to actually migrate that
6423 * task.
6424 */
6425static long
6426compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
6427{
6428 long util, max_util, sum_util, energy = 0;
6429 int cpu;
6430
6431 for (; pd; pd = pd->next) {
6432 max_util = sum_util = 0;
6433 /*
6434 * The capacity state of CPUs of the current rd can be driven by
6435 * CPUs of another rd if they belong to the same performance
6436 * domain. So, account for the utilization of these CPUs too
6437 * by masking pd with cpu_online_mask instead of the rd span.
6438 *
6439 * If an entire performance domain is outside of the current rd,
6440 * it will not appear in its pd list and will not be accounted
6441 * by compute_energy().
6442 */
6443 for_each_cpu_and(cpu, perf_domain_span(pd), cpu_online_mask) {
6444 util = cpu_util_next(cpu, p, dst_cpu);
6445 util = schedutil_energy_util(cpu, util);
6446 max_util = max(util, max_util);
6447 sum_util += util;
6448 }
6449
6450 energy += em_pd_energy(pd->em_pd, max_util, sum_util);
6451 }
6452
6453 return energy;
6454}
6455
6456/*
6381 * select_task_rq_fair: Select target runqueue for the waking task in domains 6457 * select_task_rq_fair: Select target runqueue for the waking task in domains
6382 * that have the 'sd_flag' flag set. In practice, this is SD_BALANCE_WAKE, 6458 * that have the 'sd_flag' flag set. In practice, this is SD_BALANCE_WAKE,
6383 * SD_BALANCE_FORK, or SD_BALANCE_EXEC. 6459 * SD_BALANCE_FORK, or SD_BALANCE_EXEC.