From: Peter Zijlstra <peterz@infradead.org>
To: Quentin Perret <quentin.perret@arm.com>
Cc: rjw@rjwysocki.net, linux-kernel@vger.kernel.org,
linux-pm@vger.kernel.org, gregkh@linuxfoundation.org,
mingo@redhat.com, dietmar.eggemann@arm.com,
morten.rasmussen@arm.com, chris.redpath@arm.com,
patrick.bellasi@arm.com, valentin.schneider@arm.com,
vincent.guittot@linaro.org, thara.gopinath@linaro.org,
viresh.kumar@linaro.org, tkjos@google.com,
joel@joelfernandes.org, smuckle@google.com,
adharmap@codeaurora.org, skannan@codeaurora.org,
pkondeti@codeaurora.org, juri.lelli@redhat.com,
edubezval@gmail.com, srinivas.pandruvada@linux.intel.com,
currojerez@riseup.net, javi.merino@kernel.org
Subject: Re: [PATCH v7 12/14] sched/fair: Select an energy-efficient CPU on task wake-up
Date: Thu, 4 Oct 2018 11:44:12 +0200 [thread overview]
Message-ID: <20181004094412.GD19252@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <20180912091309.7551-13-quentin.perret@arm.com>
On Wed, Sep 12, 2018 at 10:13:07AM +0100, Quentin Perret wrote:
> + while (pd) {
> + unsigned long cur_energy, spare_cap, max_spare_cap = 0;
> + int max_spare_cap_cpu = -1;
> +
> + for_each_cpu_and(cpu, perf_domain_span(pd), sched_domain_span(sd)) {
Which of the two masks do we expect to be the smallest?
> + if (!cpumask_test_cpu(cpu, &p->cpus_allowed))
> + continue;
> +
> + /* Skip CPUs that will be overutilized. */
> + util = cpu_util_next(cpu, p, cpu);
> + cpu_cap = capacity_of(cpu);
> + if (cpu_cap * 1024 < util * capacity_margin)
> + continue;
> +
> + /* Always use prev_cpu as a candidate. */
> + if (cpu == prev_cpu) {
> + prev_energy = compute_energy(p, prev_cpu, head);
> + if (prev_energy < best_energy)
> + best_energy = prev_energy;
best_energy = min(best_energy, prev_energy);
That's both shorter and clearer.
> + continue;
> + }
> +
> + /*
> + * Find the CPU with the maximum spare capacity in
> + * the performance domain
> + */
> + spare_cap = cpu_cap - util;
> + if (spare_cap > max_spare_cap) {
> + max_spare_cap = spare_cap;
> + max_spare_cap_cpu = cpu;
> + }
Sometimes I wonder if something like:
#define min_filter(varp, val) \
({ \
typeof(varp) _varp = (varp); \
typeof(val) _val = (val); \
bool f = false; \
\
if (_val < *_varp) { \
*_varp = _val; \
f = true; \
} \
\
f; \
})
and the corresponding max_filter() are worth the trouble; it would allow
writing:
if (max_filter(&max_spare_cap, spare_cap))
max_spare_cap_cpu = cpu;
and:
> + }
> +
> + /* Evaluate the energy impact of using this CPU. */
> + if (max_spare_cap_cpu >= 0) {
> + cur_energy = compute_energy(p, max_spare_cap_cpu, head);
> + if (cur_energy < best_energy) {
> + best_energy = cur_energy;
> + best_energy_cpu = max_spare_cap_cpu;
> + }
if (min_filter(&best_energy, cur_energy))
best_energy_cpu = max_spare_cap_cpu;
But then I figure, it is not... dunno. We do lots of this stuff.
> + }
> + pd = pd->next;
> + }
> +
> + /*
> + * Pick the best CPU if prev_cpu cannot be used, or if it saves at
> + * least 6% of the energy used by prev_cpu.
> + */
> + if (prev_energy == ULONG_MAX ||
> + (prev_energy - best_energy) > (prev_energy >> 4))
> + return best_energy_cpu;
Does that become more readable if we split that into two conditions?
if (prev_energy == ULONG_MAX)
return best_energy_cpu;
if ((prev_energy - best_energy) > (prev_energy >> 4))
return best_energy_cpu;
> + return prev_cpu;
> +}
> +
> /*
> * select_task_rq_fair: Select target runqueue for the waking task in domains
> * that have the 'sd_flag' flag set. In practice, this is SD_BALANCE_WAKE,
> @@ -6360,13 +6468,37 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
> int want_affine = 0;
> int sync = (wake_flags & WF_SYNC) && !(current->flags & PF_EXITING);
>
> + rcu_read_lock();
> if (sd_flag & SD_BALANCE_WAKE) {
> record_wakee(p);
> +
> + /*
> + * Forkees are not accepted in the energy-aware wake-up path
> + * because they don't have any useful utilization data yet and
> + * it's not possible to forecast their impact on energy
> + * consumption. Consequently, they will be placed by
> + * find_idlest_cpu() on the least loaded CPU, which might turn
> + * out to be energy-inefficient in some use-cases. The
> + * alternative would be to bias new tasks towards specific types
> + * of CPUs first, or to try to infer their util_avg from the
> + * parent task, but those heuristics could hurt other use-cases
> + * too. So, until someone finds a better way to solve this,
> + * let's keep things simple by re-using the existing slow path.
> + */
> + if (sched_feat(ENERGY_AWARE)) {
> + struct root_domain *rd = cpu_rq(cpu)->rd;
> + struct perf_domain *pd = rcu_dereference(rd->pd);
> +
> + if (pd && !READ_ONCE(rd->overutilized)) {
> + new_cpu = find_energy_efficient_cpu(p, prev_cpu, pd);
> + goto unlock;
> + }
> + }
> +
> + want_affine = !wake_wide(p) && !wake_cap(p, cpu, prev_cpu) &&
> + cpumask_test_cpu(cpu, &p->cpus_allowed);
> }
I would much prefer this to be something like:
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index a8f601edd958..5475a885ec9f 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -6299,12 +6299,19 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
{
struct sched_domain *tmp, *sd = NULL;
int cpu = smp_processor_id();
- int new_cpu = prev_cpu;
+ unsigned int new_cpu = prev_cpu;
int want_affine = 0;
int sync = (wake_flags & WF_SYNC) && !(current->flags & PF_EXITING);
if (sd_flag & SD_BALANCE_WAKE) {
record_wakee(p);
+
+ if (static_branch_unlikely(sched_eas_balance)) {
+ new_cpu = select_task_rq_eas(p, prev_cpu, sd_flags, wake_flags);
+ if (new_cpu < nr_cpu_ids)
+ return new_cpu;
+ }
+
want_affine = !wake_wide(p) && !wake_cap(p, cpu, prev_cpu)
&& cpumask_test_cpu(cpu, &p->cpus_allowed);
}
and then hide everything (including that giant comment) in
select_task_rq_eas().
next prev parent reply other threads:[~2018-10-04 9:44 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-12 9:12 [PATCH v7 00/14] Energy Aware Scheduling Quentin Perret
2018-09-12 9:12 ` [PATCH v7 01/14] sched: Relocate arch_scale_cpu_capacity Quentin Perret
2018-09-12 9:12 ` [PATCH v7 02/14] sched/cpufreq: Prepare schedutil for Energy Aware Scheduling Quentin Perret
2018-09-12 14:56 ` Vincent Guittot
2018-09-12 14:56 ` Vincent Guittot
2018-09-18 21:33 ` Rafael J. Wysocki
2018-09-18 21:33 ` Rafael J. Wysocki
2018-09-27 12:17 ` Quentin Perret
2018-09-27 12:17 ` Quentin Perret
2018-09-28 8:23 ` Rafael J. Wysocki
2018-09-28 8:23 ` Rafael J. Wysocki
2018-09-28 8:35 ` Quentin Perret
2018-09-28 8:35 ` Quentin Perret
2018-09-28 8:35 ` Rafael J. Wysocki
2018-09-28 8:35 ` Rafael J. Wysocki
2018-09-12 9:12 ` [PATCH v7 03/14] PM: Introduce an Energy Model management framework Quentin Perret
2018-10-02 12:25 ` Peter Zijlstra
2018-10-02 12:54 ` Quentin Perret
2018-10-02 13:50 ` Peter Zijlstra
2018-10-02 12:30 ` Peter Zijlstra
2018-10-02 12:51 ` Quentin Perret
2018-10-02 13:48 ` Peter Zijlstra
2018-10-02 14:05 ` Quentin Perret
2018-10-02 14:29 ` Peter Zijlstra
2018-10-02 14:40 ` Quentin Perret
2018-10-02 19:12 ` Andrea Parri
2018-10-03 7:48 ` Quentin Perret
2018-09-12 9:12 ` [PATCH v7 04/14] PM / EM: Expose the Energy Model in sysfs Quentin Perret
2018-09-12 9:13 ` [PATCH v7 05/14] sched: Introduce a sched_feat for Energy Aware Scheduling Quentin Perret
2018-10-02 12:34 ` Peter Zijlstra
2018-10-02 13:08 ` Quentin Perret
2018-10-03 16:24 ` Peter Zijlstra
2018-10-04 9:57 ` Quentin Perret
2018-09-12 9:13 ` [PATCH v7 06/14] sched/topology: Reference the Energy Model of CPUs when available Quentin Perret
2018-10-02 12:36 ` Peter Zijlstra
2018-10-02 13:16 ` Quentin Perret
2018-09-12 9:13 ` [PATCH v7 07/14] sched/topology: Lowest CPU asymmetry sched_domain level pointer Quentin Perret
2018-09-12 9:13 ` [PATCH v7 08/14] sched/topology: Disable EAS on inappropriate platforms Quentin Perret
2018-10-03 16:27 ` Peter Zijlstra
2018-10-04 9:10 ` Quentin Perret
2018-10-04 9:38 ` Peter Zijlstra
2018-10-04 9:45 ` Quentin Perret
2018-09-12 9:13 ` [PATCH v7 09/14] sched/fair: Clean-up update_sg_lb_stats parameters Quentin Perret
2018-09-12 9:13 ` [PATCH v7 10/14] sched: Add over-utilization/tipping point indicator Quentin Perret
2018-09-12 9:13 ` [PATCH v7 11/14] sched/fair: Introduce an energy estimation helper function Quentin Perret
2018-10-04 8:34 ` Peter Zijlstra
2018-10-04 9:02 ` Quentin Perret
2018-09-12 9:13 ` [PATCH v7 12/14] sched/fair: Select an energy-efficient CPU on task wake-up Quentin Perret
2018-10-04 9:44 ` Peter Zijlstra [this message]
2018-10-04 10:27 ` Quentin Perret
2018-10-04 10:41 ` Peter Zijlstra
2018-10-04 10:55 ` Quentin Perret
2018-10-04 12:18 ` Peter Zijlstra
2018-09-12 9:13 ` [PATCH v7 13/14] sched/topology: Make Energy Aware Scheduling depend on schedutil Quentin Perret
2018-10-04 10:50 ` Peter Zijlstra
2018-10-04 11:58 ` Quentin Perret
2018-09-12 9:13 ` [PATCH v7 14/14] OPTIONAL: cpufreq: dt: Register an Energy Model Quentin Perret
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181004094412.GD19252@hirez.programming.kicks-ass.net \
--to=peterz@infradead.org \
--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=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=morten.rasmussen@arm.com \
--cc=patrick.bellasi@arm.com \
--cc=pkondeti@codeaurora.org \
--cc=quentin.perret@arm.com \
--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 \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.