mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Pierre Gondois <pierre.gondois@arm.com>
To: Vincent Guittot <vincent.guittot@linaro.org>,
	mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com,
	dietmar.eggemann@arm.com, rostedt@goodmis.org,
	bsegall@google.com, mgorman@suse.de, vschneid@redhat.com,
	lukasz.luba@arm.com, rafael.j.wysocki@intel.com,
	linux-kernel@vger.kernel.org
Cc: qyousef@layalina.io, hongyan.xia2@arm.com,
	christian.loehle@arm.com, luis.machado@arm.com,
	qperret@google.com
Subject: Re: [PATCH 3/7 v5] sched/fair: Rework feec() to use cost instead of spare capacity
Date: Wed, 12 Mar 2025 15:08:51 +0100	[thread overview]
Message-ID: <24bc804e-305f-4273-922a-a24070aa3e56@arm.com> (raw)
In-Reply-To: <20250302210539.1563190-4-vincent.guittot@linaro.org>

Hello Vincent,

On 3/2/25 22:05, Vincent Guittot wrote:
> feec() looks for the CPU with highest spare capacity in a PD assuming that
> it will be the best CPU from a energy efficiency PoV because it will
> require the smallest increase of OPP. Although this is true generally
> speaking, this policy also filters some others CPUs which will be as
> efficients because of using the same OPP.
> In fact, we really care about the cost of the new OPP that will be
> selected to handle the waking task. In many cases, several CPUs will end
> up selecting the same OPP and as a result using the same energy cost. In
> these cases, we can use other metrics to select the best CPU for the same
> energy cost.
> 
> Rework feec() to look 1st for the lowest cost in a PD and then the most
> performant CPU between CPUs. The cost of the OPP remains the only
> comparison criteria between Performance Domains.
> 
> Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
> ---
>   kernel/sched/fair.c | 466 +++++++++++++++++++++++---------------------
>   1 file changed, 246 insertions(+), 220 deletions(-)
> 
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index d3d1a2ba6b1a..a9b97bbc085f 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c

[...]

> +static bool update_best_cpu(struct energy_cpu_stat *target,
> +			    struct energy_cpu_stat *min,
> +			    int prev, struct sched_domain *sd)
>   {
> -	unsigned long max_util = eenv_pd_max_util(eenv, pd_cpus, p, dst_cpu);
> -	unsigned long busy_time = eenv->pd_busy_time;
> -	unsigned long energy;
> -
> -	if (dst_cpu >= 0)
> -		busy_time = min(eenv->pd_cap, busy_time + eenv->task_busy_time);
> +	/*  Select the one with the least number of running tasks */
> +	if (target->nr_running < min->nr_running)
> +		return true;
> +	if (target->nr_running > min->nr_running)
> +		return false;
>   
> -	energy = em_cpu_energy(pd->em_pd, max_util, busy_time, eenv->cpu_cap);
> +	/* Favor previous CPU otherwise */
> +	if (target->cpu == prev)
> +		return true;
> +	if (min->cpu == prev)
> +		return false;
>   
> -	trace_sched_compute_energy_tp(p, dst_cpu, energy, max_util, busy_time);
> +	/*
> +	 * Choose CPU with lowest contention. One might want to consider load
> +	 * instead of runnable but we are supposed to not be overutilized so
> +	 * there is enough compute capacity for everybody.
> +	 */

I'm not sure I understand the comment. With UCLAMP_MAX tasks, a CPU can lack
compute capacity while not being tagged as overutilized. IIUC this is actually
the goal of UCLAMP_MAX.

With the following workload:
- 2 tasks A with duty_cycle=30%, UCLAMP_MIN/MAX=(0,1), niceness=0
- 2 tasks B with duty_cycle=70%, UCLAMP_MIN/MAX=(0,1), niceness=-10
The workload runs on a Pixel6 with a reduced cpuset of [1,2,7], i.e. 2 little
CPUs (1,2) capa=160 and one big CPU (7) capa=1024.
CPU7 is avoided by the tasks as their UCLAMP_MAX setting make them fit on the
little CPUs.

select_best_cpu() prefers to place tasks based on nr_running. If the 2 tasks A
end up being placed on one little CPU, and the 2 tasks B are placed on the
other little CPU, feec() is theoretically unable to balance the workload.
In practice, a kworker ends up spawning on one of these 2 little CPUs and tasks
are shuffled, so the pattern breaks after ~30ms.

This pattern seems problematic as tasks A are:
- smaller (30% < 70%)
- nicer (0 > -10)
than tasks B. So I assume the correct task placement should be one task of each
type on each little CPU.

------

There are some comments in the load balancer code:
1.
/* Computing avg_load makes sense only when group is overloaded */
2.
/*
* Computing avg_load makes sense only when group is fully busy or
* overloaded
*/

IIUC, the load is only meaningful when there is not enough compute capacity
to estimate the task size, otherwise util_avg makes more sense. It seems that
when it comes to UCLAMP_MAX task, CPUs are placed in this exact situation:
load_avg makes more sense that util_avg.
However, in this situation, energy computations also lose sense since they
are based on the util_avg values.

------

select_best_cpu() could check the CPU load before checking nr_running, but it
would be meaningless if there is enough CPU time for all the tasks.

Maybe CPU load should then be checked only if the system doesn't have enough
CPU time. But this would be equivalent to:
- remove UCLAMP_MAX in cpu_overutilized()
- when the system is overutilized (no UCLAMP_MAX involved), go back to the
   load balancer

In other words, I don't really see how it is possible to reconciliate UCLAMP_MAX
tasks with EAS as EAS relies on util_avg values, and UCLAMP_MAX forces to
rely on load_avg value rather than util_avg.

Regards,
Pierre


> +	if ((target->runnable * min->capa * sd->imbalance_pct) >=
> +			(min->runnable * target->capa * 100))
> +		return false;
>   
> -	return energy;
> +	return true;
>   }

  reply	other threads:[~2025-03-12 14:09 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-02 21:05 [PATCH 0/7 v5] sched/fair: Rework EAS to handle more cases Vincent Guittot
2025-03-02 21:05 ` [PATCH 1/7 v5] sched/fair: Filter false overloaded_group case for EAS Vincent Guittot
2025-03-04  4:38   ` K Prateek Nayak
2025-03-05  8:13     ` Vincent Guittot
2025-03-02 21:05 ` [PATCH 2/7 v5] energy model: Add a get previous state function Vincent Guittot
2025-03-02 21:05 ` [PATCH 3/7 v5] sched/fair: Rework feec() to use cost instead of spare capacity Vincent Guittot
2025-03-12 14:08   ` Pierre Gondois [this message]
2025-03-14 16:24     ` Vincent Guittot
2025-03-16 20:21       ` Pierre Gondois
2025-03-25 11:09   ` Pierre Gondois
2025-03-02 21:05 ` [PATCH 4/7 v5] energy model: Remove unused em_cpu_energy() Vincent Guittot
2025-03-02 21:05 ` [PATCH 5/7 v5] sched/fair: Add push task mechanism for EAS Vincent Guittot
2025-03-07 12:51   ` kernel test robot
2025-03-10 12:47   ` kernel test robot
2025-03-10 18:20   ` Shrikanth Hegde
2025-03-11 16:27     ` Vincent Guittot
2025-03-19 15:26   ` Valentin Schneider
2025-03-24 16:34   ` Christian Loehle
2025-03-25 11:16   ` Christian Loehle
2025-04-15 13:52     ` Vincent Guittot
2025-04-16 13:52       ` Christian Loehle
2025-04-15  2:31   ` Xuewen Yan
2025-04-15 13:51     ` Vincent Guittot
2025-04-16  2:03       ` Xuewen Yan
2025-03-02 21:05 ` [PATCH 6/7 v5] sched/fair: Add misfit case to push task mecanism " Vincent Guittot
2025-03-24 16:06   ` Christian Loehle
2025-03-02 21:05 ` [PATCH 7/7 v5] sched/fair: Update overutilized detection Vincent Guittot
2025-03-24 16:41 ` [PATCH 0/7 v5] sched/fair: Rework EAS to handle more cases Christian Loehle
2025-04-03 12:36 ` Christian Loehle
2025-04-15 13:49   ` Vincent Guittot
2025-04-16 10:51     ` Christian Loehle

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=24bc804e-305f-4273-922a-a24070aa3e56@arm.com \
    --to=pierre.gondois@arm.com \
    --cc=bsegall@google.com \
    --cc=christian.loehle@arm.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=hongyan.xia2@arm.com \
    --cc=juri.lelli@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luis.machado@arm.com \
    --cc=lukasz.luba@arm.com \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=qperret@google.com \
    --cc=qyousef@layalina.io \
    --cc=rafael.j.wysocki@intel.com \
    --cc=rostedt@goodmis.org \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®