On 08/25/20 09:59, Yun Hsiang wrote:
This does sound ideal to me too. But how do you handle the other 20% range, e.g: util_min = 850? In this case another medium CPU could be a better fit and more energy efficient.
If you can improve your patch to handle this 20% scenario and send it as RFC to LKML, it'll help pushing things more forward in this direction :-)
Thanks for the feedback. I think the patch can be modified like this. If there is no CPU can pass fit_capacity, select sys_max_spare_cap_cpu. If there are any CPU that can fit it, find the CPU with the best energy.
if (prev_delta == ULONG_MAX) { /* Pick system max spare cpu if all cpu cannot fit requirement. */ if (best_energy_cpu == prev_cpu) return sys_max_spare_cap_cpu; else return best_energy_cpu; }
If you think this modification is fine, I'll send it as RFC to LKML.
Sorry for the delayed response. It's LPC this week so busy with that. And next week I am on holiday.
I suggest creating a proper patch that has:
1. Good explanation of the problem. 2. Good explanation of your proposed solution. 3. Any limitations you are aware of. 4. Any open questions you have that needs addressing.
And tag it as RFC so people would know it's WIP.
AFAICS now, I don't think what you have is enough because you don't explicitly check if the task was boosted
if (beset_energy_cpu == prev_cpu /!! && boosted !!/) { ... }
But I might have looked at it in a haste..
Still not tested, but how does the patch below behave for you? Maybe it needs to be combined with your patch to look for max_spare_capacity_cpu. But I'd be interested to see how it behaves on its own too.
Anyway. Your patch doesn't have to be perfect to be posted to LKML if it's tagged with RFC. We can have wider audience for discussion there :-)
Thanks!
-- Qais Yousef
-->8--
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 1a68a0536add..7af5c3eca517 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -113,6 +113,13 @@ int __weak arch_asym_cpu_priority(int cpu) */ #define fits_capacity(cap, max) ((cap) * 1280 < (max) * 1024)
+/* + * When a task is boosted, we want to ignore the 20% margin rule as the task + * has inflated itself to run on a bigger core. That threshold will be + * honoured once the tasks real util reaches the threshold. + */ +#define fits_capacity_boosted(cap, max) ((cap) <= (max)) + #endif
#ifdef CONFIG_CFS_BANDWIDTH @@ -6555,7 +6562,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) { unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX; struct root_domain *rd = cpu_rq(smp_processor_id())->rd; - unsigned long cpu_cap, util, base_energy = 0; + unsigned long cpu_cap, uclamp_util, util, base_energy = 0; int cpu, best_energy_cpu = prev_cpu; struct sched_domain *sd; struct perf_domain *pd; @@ -6603,10 +6610,19 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) * much capacity we can get out of the CPU; this is * aligned with schedutil_cpu_util(). */ - util = uclamp_rq_util_with(cpu_rq(cpu), util, p); - if (!fits_capacity(util, cpu_cap)) + uclamp_util = uclamp_rq_util_with(cpu_rq(cpu), util, p); + + if (uclamp_util <= util && + !fits_capacity(uclamp_util, cpu_cap)) { + continue;
+ } else if (uclamp_util > util && + !fits_capacity_boosted(uclamp_util, cpu_cap)) { + + continue; + } + /* Always use prev_cpu as a candidate. */